using NUnit.Framework;
using SlatedGameToolkit.Framework.Utilities.Collections;

namespace SlatedGameToolkit.Framework.Tests.Utilities.Collections.Caching
{
    public class LRUCacheTests
    {
        [SetUp]
        public void Setup()
        {
        }

        [Test]
        public void SizeLimitTest()
        {
            LRUCache<int, int> cache = new LRUCache<int, int>(16);
            for (int i = 0; i < 32; i++) {
                cache.Set(i, i);
            }

            Assert.AreEqual(16, cache.Count);
        }

        [Test]
        public void ResizeLimitTest() {
            LRUCache<int, int> cache = new LRUCache<int, int>(16);
            for (int i = 0; i < 32; i++) {
                cache.Set(i, i);
            }
            cache.MaxLength = 64;
            for (int i = 32; i < 64; i++) {
                cache.Set(i, i);
            }

            Assert.AreEqual(48, cache.Count);
            Assert.AreEqual(63, cache[63]);
        }

        [Test]
        public void LeastUsedTest() {
            LRUCache<int, int> cache = new LRUCache<int, int>(4);
            for (int i = 0; i < cache.MaxLength; i++) {
                cache[i] = i;
            }
            int used = cache[0];
            Assert.AreEqual(0, used);
            cache[4] = 4;
            Assert.IsFalse(cache.ContainsKey(1));
            cache[2] = 2;
            cache[5] = 5;
            Assert.IsTrue(cache.ContainsKey(2));
        }

        [Test]
        public void ComputeIfNonexistentTest() {
            LRUCache<int, int> cache = new LRUCache<int, int>(4);
            for (int i = 0; i < cache.MaxLength; i++) {
                cache.ComputeIfNonExistent(i, (a) => a);
            }
        }

        [Test]
        public void ComputeIfNonexistentTestExists() {
            LRUCache<int, int> cache = new LRUCache<int, int>(4);
            for (int i = 0; i < cache.MaxLength; i++) {
                cache.ComputeIfNonExistent(i, (a) => a);
            }

            for (int i = 0; i < cache.MaxLength; i++) {
                Assert.AreEqual(i, cache.ComputeIfNonExistent(i, (a) => -a));
            }
        }
    }
}