using System;
using NUnit.Framework;
using Unity.PerformanceTesting;
using UnityEngine.Events;

public class UnityEventTests
{
    private UnityEvent<int> _event;

    private void Setup () => _event = new();
    private void Teardown ()
    {
        _event.RemoveAllListeners();
        _event = default;
    }

    private void SubscribeEvent()
    {
        _event.AddListener(NoOpInt);
        _event.AddListener(IncrementInt);
        _event.AddListener(_ => NoOp());
    }

    private void UnsubscribeEvent ()
    {
        _event.RemoveListener(NoOpInt);
        _event.RemoveListener(IncrementInt);
        _event.RemoveListener(NoOpAction);
    }

    [Test, Performance]
    public void Subscribe () => Measure.Method(SubscribeEvent).WarmupCount(5).MeasurementCount(100).SetUp(Setup).CleanUp(Teardown).Run();

    [Test, Performance]
    public void Unsubscribe()
    {
        Measure.Method(UnsubscribeEvent).WarmupCount(5).MeasurementCount(100).SetUp(() => { Setup(); SubscribeEvent(); }).CleanUp(Teardown).Run();
    }

    [Test, Performance]
    public void Invoke()
    {
        Measure.Method(() => _event.Invoke(0)).WarmupCount(5).MeasurementCount(100).SetUp(() => { Setup(); SubscribeEvent(); }).CleanUp(Teardown).Run();
    }

    private UnityAction<int> NoOpAction = _ => NoOp();
    private static void NoOp() { }
    private void NoOpInt(int i) { }
    private void IncrementInt(int i) { i++; }
}