/**
 * MCP resources: initialize must advertise the `resources` capability when a
 * provider is wired, and resources/list + resources/read must route to it.
 *
 * Why this matters: Claude Desktop only SHOWS things a server exposes as
 * resources. Before this, the server advertised only `tools`, so repos never
 * appeared in the app's picker and users thought the repo "wasn't there".
 * These tests lock the wiring with a stub provider (no DB needed).
 */
import { describe, it, expect } from "bun:test";
import { routeMcpRequest } from "../lib/mcp";

const ctx = { userId: "u1", scopes: ["repo"] };
const tools = {};

const stubResources = {
  list: async () => ({
    resources: [
      { uri: "gluecron://repo/ccantynz/Vapron", name: "ccantynz/Vapron" },
    ],
  }),
  read: async (uri: string) => ({
    contents: [{ uri, mimeType: "text/markdown", text: "# hello" }],
  }),
};

function rpc(method: string, params?: unknown) {
  return { jsonrpc: "2.0" as const, id: 1, method, params };
}

describe("MCP resources capability", () => {
  it("initialize advertises resources when a provider is wired", async () => {
    const res: any = await routeMcpRequest(rpc("initialize"), {
      ctx,
      tools,
      resources: stubResources,
    });
    expect(res.result.capabilities.resources).toBeDefined();
    expect(res.result.capabilities.tools).toBeDefined();
  });

  it("initialize omits resources when NO provider is wired", async () => {
    const res: any = await routeMcpRequest(rpc("initialize"), { ctx, tools });
    expect(res.result.capabilities.resources).toBeUndefined();
  });

  it("resources/list routes to the provider", async () => {
    const res: any = await routeMcpRequest(rpc("resources/list"), {
      ctx,
      tools,
      resources: stubResources,
    });
    expect(res.result.resources).toHaveLength(1);
    expect(res.result.resources[0].uri).toBe("gluecron://repo/ccantynz/Vapron");
  });

  it("resources/read passes the uri through and returns contents", async () => {
    const res: any = await routeMcpRequest(
      rpc("resources/read", { uri: "gluecron://repo/ccantynz/Vapron" }),
      { ctx, tools, resources: stubResources }
    );
    expect(res.result.contents[0].text).toBe("# hello");
  });

  it("resources/read without a uri is an invalid-params error", async () => {
    const res: any = await routeMcpRequest(rpc("resources/read", {}), {
      ctx,
      tools,
      resources: stubResources,
    });
    expect(res.error).toBeDefined();
    expect(res.error.code).toBe(-32602);
  });

  it("resources/list with no provider returns an empty list (no crash)", async () => {
    const res: any = await routeMcpRequest(rpc("resources/list"), { ctx, tools });
    expect(res.result.resources).toEqual([]);
  });
});
