import { describe, expect, test } from "bun:test";
import {
  describeSipDiscoveryResult,
  discoverRingCentralSipDevice,
  redactSipEnv,
  sipEnvFromRingCentral,
} from "./ringcentral-sip-discovery.ts";
import type { McpToolCaller } from "./mcp-tool-client.ts";

describe("RingCentral SIP discovery", () => {
  test("finds Other Phone device and redacts SIP password", async () => {
    const result = await discoverRingCentralSipDevice({ admin: new FakeAdmin() });

    expect(result.ok).toBe(true);
    expect(result.otherPhoneCandidates[0]?.deviceId).toBe("device-1");
    expect(result.sipEnv?.RINGCENTRAL_SIP_OUTBOUND_PROXY).toBe("sip10.ringcentral.com:5096");
    expect(redactSipEnv(result.sipEnv!).RINGCENTRAL_SIP_PASSWORD).toBe("<redacted:6>");
  });

  test("reports missing Other Phone device without reading SIP secrets", async () => {
    const admin = new FakeAdmin({ deviceType: "HardPhone" });
    const result = await discoverRingCentralSipDevice({ admin });

    expect(result.ok).toBe(false);
    expect(result.reason).toMatch(/No Other Phone/);
    expect(describeSipDiscoveryResult(result)).toContain("Matching extension(s): 9001 AI Scheduling Backup");
    expect(admin.calls).not.toContain("read_device_sip_info");
  });

  test("describes missing AI extension distinctly from missing device", async () => {
    const result = await discoverRingCentralSipDevice({
      admin: new FakeAdmin({
        extensionRecords: [
          {
            id: "ext-2",
            extensionNumber: "105",
            name: "Front Desk",
            type: "User",
            status: "Enabled",
          },
        ],
      }),
    });

    expect(result.ok).toBe(false);
    expect(result.matchingExtensions).toEqual([]);
    expect(describeSipDiscoveryResult(result)).toMatch(/No enabled AI Scheduling Backup extension/);
  });

  test("normalizes RingCentral SIP info into live env", () => {
    expect(
      sipEnvFromRingCentral({
        domain: "sip.ringcentral.com",
        userName: "16505550100",
        password: "secret",
        authorizationId: "auth-id",
        outboundProxies: [{ region: "NA", proxyTLS: "sip10.ringcentral.com:5096" }],
      }),
    ).toEqual({
      RINGCENTRAL_SIP_DOMAIN: "sip.ringcentral.com",
      RINGCENTRAL_SIP_OUTBOUND_PROXY: "sip10.ringcentral.com:5096",
      RINGCENTRAL_SIP_USERNAME: "16505550100",
      RINGCENTRAL_SIP_PASSWORD: "secret",
      RINGCENTRAL_SIP_AUTHORIZATION_ID: "auth-id",
      RINGCENTRAL_SIP_CODEC: "OPUS/16000",
    });
  });
});

class FakeAdmin implements McpToolCaller {
  calls: string[] = [];

  constructor(
    private readonly opts: {
      deviceType?: string;
      extensionRecords?: Array<Record<string, unknown>>;
    } = {},
  ) {}

  async callTool(name: string): Promise<unknown> {
    this.calls.push(name);
    if (name === "list_extensions") {
      return {
        records: this.opts.extensionRecords ?? [
          {
            id: "ext-1",
            extensionNumber: "9001",
            name: "AI Scheduling Backup",
            type: "User",
            status: "Enabled",
          },
        ],
      };
    }
    if (name === "list_extension_devices") {
      return {
        records: [
          {
            id: "device-1",
            name: "AI Existing Phone",
            type: this.opts.deviceType ?? "Other Phone",
            status: "Offline",
          },
        ],
      };
    }
    if (name === "read_device_sip_info") {
      return {
        domain: "sip.ringcentral.com",
        userName: "16505550100",
        password: "secret",
        authorizationId: "auth-id",
        outboundProxies: [{ region: "NA", proxyTLS: "sip10.ringcentral.com:5096" }],
      };
    }
    throw new Error(`unexpected tool ${name}`);
  }

  async listTools(): Promise<string[]> {
    return [];
  }

  async close(): Promise<void> {}
}
