import { describe, expect, test } from "bun:test";
import type { VoiceAgentConfig } from "./config.ts";
import { runMcpSmoke, selectAvailableTool } from "./mcp-smoke.ts";
import type { McpToolCaller } from "./mcp-tool-client.ts";

describe("MCP smoke", () => {
  test("selects the first available candidate tool", () => {
    expect(selectAvailableTool(["b", "c"], ["a", "b"])).toBe("b");
  });

  test("runs required checks without exposing raw tool payloads", async () => {
    const report = await runMcpSmoke(config(), {
      clientFactory: (endpoint) => new FakeMcpClient(endpoint.name),
      env: {},
    });

    expect(report.ok).toBe(true);
    expect(report.checks.some((check) => check.label === "AdvancedMD patient search")).toBe(true);
    expect(report.checks.find((check) => check.label === "AdvancedMD patient search")?.skipped).toBe(
      true,
    );
    expect(report.checks.find((check) => check.tool === "get_account_info")?.summary).toBe(
      "object keys: ok",
    );
  });

  test("fails checks when a tool returns an error payload", async () => {
    const report = await runMcpSmoke(config(), {
      clientFactory: (endpoint) => new FakeMcpClient(endpoint.name, { error: "invalid_client" }),
      env: {},
    });

    expect(report.ok).toBe(false);
    expect(report.checks.find((check) => check.tool === "get_account_info")?.ok).toBe(false);
  });
});

class FakeMcpClient implements McpToolCaller {
  constructor(
    private readonly service: string,
    private readonly response: unknown = { ok: true },
  ) {}

  async listTools(): Promise<string[]> {
    if (this.service === "advancedmd") {
      return ["auth_status", "login", "get_fieldset_info"];
    }
    if (this.service === "ringcentral") {
      return ["get_account_info", "list_phone_numbers", "get_call_logs"];
    }
    return [
      "get_service_status",
      "get_auth_context",
      "list_call_queues",
      "pull_call_log",
      "list_extension_devices",
      "read_device_sip_info",
    ];
  }

  async callTool(): Promise<unknown> {
    return this.response;
  }

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

function config(): VoiceAgentConfig {
  const endpoint = (name: string) => ({
    name,
    mcpUrl: `https://example.com/${name}/mcp`,
    bearerToken: "token",
    requiresPhiTransport: true,
  });
  return {
    defaultVoiceProvider: "openai_realtime",
    voiceProviderFailover: false,
    openai: {
      apiKey: "openai",
      model: "gpt-realtime",
      realtimeUrl: "wss://api.openai.com/v1/realtime",
      voice: "alloy",
    },
    xai: {
      apiKey: "xai",
      model: "grok-voice-think-fast-1.0",
      realtimeUrl: "wss://api.x.ai/v1/realtime",
      voice: "eve",
      phiAllowed: false,
    },
    audio: {
      ringCentralFormat: { codec: "opus", sampleRateHz: 16000, channels: 1 },
      providerFormat: { codec: "pcm16", sampleRateHz: 16000, channels: 1 },
    },
    mcp: {
      advancedmd: endpoint("advancedmd"),
      ringcentral: endpoint("ringcentral"),
      ringcentralAdmin: endpoint("ringcentral-admin"),
    },
    scheduling: {
      maxConcurrentTransactions: 1,
      amdLookupTimeoutMs: 6000,
    },
  };
}
