using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using UnityEngine.Tilemaps;

public class TestLevelManager
{
    private ResourceTile _farm;
    private Tilemap _tilemap;
    const int size = 25;
    const int sqrt_size = 5;

    private YieldInstruction Timing => new WaitForSeconds(0.1f);
    [SetUp]
    public void SetUp()
    {
        new GameObject("LevelManager").AddComponent<LevelManagerScript>();
        _farm = ScriptableObject.CreateInstance<ResourceTile>();
        _farm.name = nameof(_farm);

        _tilemap = new GameObject("Tilemap").AddComponent<Tilemap>();
        _tilemap.tileAnchor = Vector3.zero;
        for (int i = 0; i < size; i++)
        {
            var pos = new Vector3Int(i % sqrt_size, i / sqrt_size);
            _tilemap.SetTile(pos, _farm);
        }
    }
    [TearDown]
    public void TearDown()
    {
        Object.Destroy(_tilemap.gameObject);
    }

    // A UnityTest behaves like a coroutine in Play Mode. In Edit Mode you can use
    // `yield return null;` to skip a frame.
    [UnityTest]
    public IEnumerator TestLevelManagerWithEnumeratorPasses()
    {
        yield return Timing;
        Assert.AreEqual(size, LevelManager.Instance.Count<ResourceTile>(), "there should be " + size + " tiles");
        for (int i = 0; i < 25; i++)
        {
            var pos = new Vector3(i % sqrt_size, i / sqrt_size);
            var tileExists = LevelManager.Instance.Has<ResourceTile>(t => Mathf.Approximately(Vector2.Distance(pos, t.Position), 0));
            Assert.True(tileExists, "there should be a tile at position " + pos);
        }

        var newPos = new Vector3Int(-5, -5);
        _tilemap.SetTile(newPos, _farm);
        yield return Timing;

        var newTileExists = LevelManager.Instance.Has<ResourceTile>(t => Mathf.Approximately(Vector3.Distance(t.Position, newPos), 0));
        Assert.True(newTileExists, "new tile wasn't added to level manager");
    }
}
