import { Type } from "@sinclair/typebox";
import { describe, expect, test } from "bun:test";

import type { Checker } from "../../../../src/server/checker/runner/types";
import type { CheckResult, ResolvedTargetBase } from "../../../../src/server/checker/types";

import { createDefaultCheckerRegistry } from "../../../../src/server/checker/runner";
import { CheckerRegistry } from "../../../../src/server/checker/runner/registry";

function createChecker(type: string): Checker {
  return {
    buildDetail: () => null,
    configKey: type,
    execute: () => Promise.resolve<CheckResult>({} as unknown as CheckResult),
    resolve: () => ({}) as unknown as ResolvedTargetBase,
    schemas: {
      config: Type.Object({}, { additionalProperties: false }),
      defaults: Type.Object({}, { additionalProperties: false }),
      expect: Type.Object({}, { additionalProperties: false }),
    },
    serialize: () => ({ config: "", target: "" }),
    type,
    validate: () => [],
  };
}

describe("CheckerRegistry", () => {
  test("注册并获取 Checker", () => {
    const registry = new CheckerRegistry();
    const checker = createChecker("http");
    registry.register(checker);
    expect(registry.get("http")).toBe(checker);
  });

  test("获取未注册的 type 抛出错误", () => {
    const registry = new CheckerRegistry();
    expect(() => registry.get("unknown")).toThrow("不支持的 probe type");
  });

  test("重复注册同一 type 抛出错误", () => {
    const registry = new CheckerRegistry();
    registry.register(createChecker("http"));
    expect(() => registry.register(createChecker("http"))).toThrow("已注册");
  });

  test("查询支持的 type 列表", () => {
    const registry = new CheckerRegistry();
    registry.register(createChecker("http"));
    registry.register(createChecker("cmd"));
    expect(registry.supportedTypes).toEqual(["http", "cmd"]);
  });

  test("definitions 返回注册定义", () => {
    const registry = new CheckerRegistry();
    const checker = createChecker("http");
    registry.register(checker);
    expect(registry.definitions).toEqual([checker]);
  });

  test("tryGet 未注册返回 undefined", () => {
    const registry = new CheckerRegistry();
    expect(registry.tryGet("missing")).toBeUndefined();
  });

  test("默认 registry 创建 fresh 实例且互不污染", () => {
    const first = createDefaultCheckerRegistry();
    const second = createDefaultCheckerRegistry();
    first.register(createChecker("custom"));

    expect(first.supportedTypes).toEqual(["http", "cmd", "db", "tcp", "icmp", "udp", "llm", "custom"]);
    expect(second.supportedTypes).toEqual(["http", "cmd", "db", "tcp", "icmp", "udp", "llm"]);
    expect(
      first.definitions.every(
        (checker) => checker.schemas.config && checker.schemas.defaults && checker.schemas.expect,
      ),
    ).toBe(true);
  });

  test("默认 registry 注册 icmp type", () => {
    const registry = createDefaultCheckerRegistry();
    expect(registry.supportedTypes).toContain("icmp");
    expect(registry.get("icmp").configKey).toBe("icmp");
  });
});
