/**
 * Regression: the v1 "repo:*" READ tools must NOT be hardcoded public-only.
 *
 * They used to reject EVERY private repo with
 *   `${owner}/${repo} is private; v1 MCP read tool is public-only`
 * even for the authenticated owner. That meant a user who signed into the
 * OAuth connector (e.g. Claude Desktop) could not read their own private
 * repos at all — Vapron never showed up. Now they gate on the caller's
 * actual access via resolveReadableRepo(): public, OR private + caller can
 * read (owner / collaborator / org member).
 *
 * Two invariants are locked here without needing a live DB:
 *   1. No read-tool description still advertises "public-only".
 *   2. Privacy contract: an unknown repo throws METHOD_NOT_FOUND (the same
 *      error a private repo the caller can't see would throw — we never
 *      confirm a private repo's existence).
 */
import { describe, it, expect } from "bun:test";
import { ERR_METHOD_NOT_FOUND, McpError } from "../lib/mcp";
import { defaultTools } from "../lib/mcp-tools";

const HAS_DB = Boolean(process.env.DATABASE_URL);
const anonCtx = { userId: null, scopes: [] };

const READ_TOOLS = [
  "gluecron_repo_read_file",
  "gluecron_repo_list_issues",
  "gluecron_repo_explain_codebase",
  "gluecron_repo_health",
  "gluecron_repo_search",
];

describe("v1 MCP read tools are no longer public-only", () => {
  it("no read-tool description advertises 'public-only'", () => {
    const tools = defaultTools();
    for (const name of READ_TOOLS) {
      const handler = tools[name];
      expect(handler).toBeDefined();
      expect(handler.tool.description.toLowerCase()).not.toContain("public-only");
    }
  });

  it.skipIf(!HAS_DB)(
    "unknown repo → METHOD_NOT_FOUND (privacy contract), for the read tools that resolve a specific repo",
    async () => {
      const tools = defaultTools();
      const cases: Array<{ name: string; args: Record<string, unknown> }> = [
        {
          name: "gluecron_repo_read_file",
          args: { owner: "nobody-xyz-fixture", repo: "nope", path: "README.md" },
        },
        {
          name: "gluecron_repo_list_issues",
          args: { owner: "nobody-xyz-fixture", repo: "nope" },
        },
        {
          name: "gluecron_repo_explain_codebase",
          args: { owner: "nobody-xyz-fixture", repo: "nope" },
        },
        {
          name: "gluecron_repo_health",
          args: { owner: "nobody-xyz-fixture", repo: "nope" },
        },
      ];
      for (const tc of cases) {
        const handler = tools[tc.name];
        await expect(handler.run(tc.args, anonCtx)).rejects.toMatchObject({
          code: ERR_METHOD_NOT_FOUND,
        });
      }
    }
  );
});
