import { describe, expect, it } from "bun:test";

import type { ContentExpectations } from "../../../../../src/server/checker/expect/types";

import {
  checkResponded,
  checkResponseSize,
  checkResponseText,
  checkSourceHost,
  checkSourcePort,
} from "../../../../../src/server/checker/runner/udp/expect";

function value(matcher: ContentExpectations[number]["matcher"]): ContentExpectations[number] {
  return { kind: "value", matcher };
}

describe("checkResponded", () => {
  it("responded=true 期望 true → 匹配", () => {
    const result = checkResponded(true, true);
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("responded=false 期望 true → 不匹配", () => {
    const result = checkResponded(false, true);
    expect(result.matched).toBe(false);
    expect(result.failure!.kind).toBe("mismatch");
    expect(result.failure!.phase).toBe("responded");
  });

  it("responded=false 期望 false → 匹配", () => {
    const result = checkResponded(false, false);
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("responded=true 期望 false → 不匹配", () => {
    const result = checkResponded(true, false);
    expect(result.matched).toBe(false);
    expect(result.failure!.kind).toBe("mismatch");
    expect(result.failure!.phase).toBe("responded");
  });
});

describe("checkResponseSize", () => {
  it("size=4 gte=4 → 匹配", () => {
    const result = checkResponseSize(4, { gte: 4 });
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("size=2 gte=4 → 不匹配，phase=responseSize", () => {
    const result = checkResponseSize(2, { gte: 4 });
    expect(result.matched).toBe(false);
    expect(result.failure!.kind).toBe("mismatch");
    expect(result.failure!.phase).toBe("responseSize");
  });

  it("size=10 lt=20 → 匹配", () => {
    const result = checkResponseSize(10, { lt: 20 });
    expect(result.matched).toBe(true);
  });

  it("size=5 equals=5 → 匹配", () => {
    const result = checkResponseSize(5, { equals: 5 });
    expect(result.matched).toBe(true);
  });
});

describe("checkResponseText", () => {
  it("单条 contains 匹配", () => {
    const result = checkResponseText("PONG", [value({ contains: "PONG" })]);
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("单条 contains 不匹配，phase=response", () => {
    const result = checkResponseText("PING", [value({ contains: "PONG" })]);
    expect(result.matched).toBe(false);
    expect(result.failure!.kind).toBe("mismatch");
    expect(result.failure!.phase).toBe("response");
  });

  it("多条规则全部匹配", () => {
    const result = checkResponseText("hello world", [value({ contains: "hello" }), value({ regex: "^hello" })]);
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("多条规则第二条失败 → 不匹配", () => {
    const result = checkResponseText("hello world", [value({ contains: "hello" }), value({ regex: "^world" })]);
    expect(result.matched).toBe(false);
    expect(result.failure!.phase).toBe("response");
    expect(result.failure!.path).toBe("response[1]");
  });
});

describe("checkSourceHost", () => {
  it("equals 匹配", () => {
    const result = checkSourceHost("127.0.0.1", { equals: "127.0.0.1" });
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("equals 不匹配", () => {
    const result = checkSourceHost("10.0.0.1", { equals: "127.0.0.1" });
    expect(result.matched).toBe(false);
    expect(result.failure!.kind).toBe("mismatch");
    expect(result.failure!.phase).toBe("sourceHost");
  });
});

describe("checkSourcePort", () => {
  it("equals 匹配", () => {
    const result = checkSourcePort(9000, { equals: 9000 });
    expect(result.matched).toBe(true);
    expect(result.failure).toBeNull();
  });

  it("equals 不匹配", () => {
    const result = checkSourcePort(8080, { equals: 9000 });
    expect(result.matched).toBe(false);
    expect(result.failure!.kind).toBe("mismatch");
    expect(result.failure!.phase).toBe("sourcePort");
  });
});
