// ---------------------------------------------------------------------------
// BT.Framework.Tests
// ObservableDictionaryTests.cs — ObservableDictionary 단위 테스트
// ---------------------------------------------------------------------------
using System.Collections.Generic;
using NUnit.Framework;
using BurningTimes.Core.Container;

namespace BurningTimes.Tests.Core.Container
{
    public class ObservableDictionaryTests
    {
        [Test]
        public void Add_EmitsAdded()
        {
            var map = new ObservableDictionary<int, string>();
            var events = new List<(int, string)>();
            map.Added += (k, v) => events.Add((k, v));

            map.Add(1, "one");

            Assert.That(events, Is.EqualTo(new[] { (1, "one") }));
        }

        [Test]
        public void IndexerOnNewKey_EmitsAdded()
        {
            var map = new ObservableDictionary<int, string>();
            int addedCount = 0;
            int updatedCount = 0;
            map.Added += (_, __) => addedCount++;
            map.Updated += (_, __, ___) => updatedCount++;

            map[1] = "one";

            Assert.That(addedCount, Is.EqualTo(1));
            Assert.That(updatedCount, Is.EqualTo(0));
        }

        [Test]
        public void IndexerOnExistingKey_EmitsUpdated()
        {
            var map = new ObservableDictionary<int, string> { { 1, "one" } };
            var events = new List<(int, string, string)>();
            map.Updated += (k, oldV, newV) => events.Add((k, oldV, newV));

            map[1] = "ONE";

            Assert.That(events, Is.EqualTo(new[] { (1, "one", "ONE") }));
        }

        [Test]
        public void Remove_EmitsRemovedWithOldValue()
        {
            var map = new ObservableDictionary<int, string> { { 1, "one" }, { 2, "two" } };
            var events = new List<(int, string)>();
            map.Removed += (k, v) => events.Add((k, v));

            Assert.IsTrue(map.Remove(1));

            Assert.That(events, Is.EqualTo(new[] { (1, "one") }));
        }

        [Test]
        public void Remove_OnMissingKey_EmitsNothing()
        {
            var map = new ObservableDictionary<int, string>();
            int removedCount = 0;
            map.Removed += (_, __) => removedCount++;

            Assert.IsFalse(map.Remove(99));
            Assert.That(removedCount, Is.EqualTo(0));
        }

        [Test]
        public void Clear_EmitsReset()
        {
            var map = new ObservableDictionary<int, string> { { 1, "one" } };
            int resetCount = 0;
            map.Reset += () => resetCount++;

            map.Clear();

            Assert.That(resetCount, Is.EqualTo(1));
            Assert.That(map.Count, Is.EqualTo(0));
        }

        [Test]
        public void Clear_OnEmpty_DoesNotEmitReset()
        {
            var map = new ObservableDictionary<int, string>();
            int resetCount = 0;
            map.Reset += () => resetCount++;

            map.Clear();

            Assert.That(resetCount, Is.EqualTo(0));
        }

        [Test]
        public void TryGetValue_Works()
        {
            var map = new ObservableDictionary<string, int> { { "a", 1 } };
            Assert.IsTrue(map.TryGetValue("a", out var v));
            Assert.That(v, Is.EqualTo(1));
            Assert.IsFalse(map.TryGetValue("missing", out _));
        }
    }
}
