import { describe, it, expect, beforeEach } from "vitest";
import { LruCache } from "../../src/shared/cache/lru.cache.js";

describe("LruCache", () => {
  let cache: LruCache;

  beforeEach(() => {
    cache = new LruCache(3);
  });

  describe("set / get", () => {
    it("应该存取值", () => {
      cache.set("key1", "value1", 60);
      expect(cache.get("key1")).toBe("value1");
    });

    it("未设置的 key 返回 null", () => {
      expect(cache.get("nonexistent")).toBeNull();
    });
  });

  describe("TTL 过期", () => {
    it("过期后返回 null", async () => {
      cache.set("key1", "value1", 0.01);
      await new Promise((resolve) => setTimeout(resolve, 20));
      expect(cache.get("key1")).toBeNull();
    });

    it("未过期时返回值", () => {
      cache.set("key1", "value1", 60);
      expect(cache.get("key1")).toBe("value1");
    });
  });

  describe("LRU 淘汰", () => {
    it("容量满时淘汰最久未使用的条目", () => {
      cache.set("a", "1", 60);
      cache.set("b", "2", 60);
      cache.set("c", "3", 60);
      cache.set("d", "4", 60);

      expect(cache.get("a")).toBeNull();
      expect(cache.get("b")).toBe("2");
      expect(cache.get("c")).toBe("3");
      expect(cache.get("d")).toBe("4");
    });

    it("访问后更新 LRU 顺序", () => {
      cache.set("a", "1", 60);
      cache.set("b", "2", 60);
      cache.set("c", "3", 60);

      cache.get("a");

      cache.set("d", "4", 60);

      expect(cache.get("a")).toBe("1");
      expect(cache.get("b")).toBeNull();
    });
  });

  describe("delete", () => {
    it("删除后返回 null", () => {
      cache.set("key1", "value1", 60);
      cache.delete("key1");
      expect(cache.get("key1")).toBeNull();
    });
  });

  describe("clear", () => {
    it("清空所有条目", () => {
      cache.set("a", "1", 60);
      cache.set("b", "2", 60);
      cache.clear();
      expect(cache.size).toBe(0);
    });
  });

  describe("size", () => {
    it("返回当前条目数", () => {
      expect(cache.size).toBe(0);
      cache.set("a", "1", 60);
      expect(cache.size).toBe(1);
      cache.set("b", "2", 60);
      expect(cache.size).toBe(2);
    });
  });

  it("默认 maxSize 为 100", () => {
    const defaultCache = new LruCache();
    for (let i = 0; i < 100; i++) {
      defaultCache.set(`key${i}`, `val${i}`, 60);
    }
    expect(defaultCache.size).toBe(100);
    defaultCache.set("key100", "val100", 60);
    expect(defaultCache.size).toBe(100);
    expect(defaultCache.get("key0")).toBeNull();
  });
});
