/**
 * Hosted Claude loops must not hand platform secrets to user code.
 *
 * `loop.sourceCode` is arbitrary user-supplied JavaScript. Creating a loop
 * requires only requireAuth (src/routes/claude-deploy.tsx:54), so any
 * registered account can run whatever it wants, and the run's stdout is
 * captured and returned to the caller. Anything placed in the subprocess env
 * is readable with a single console.log.
 *
 * The env used to carry:
 *   - GLUECRON_PAT — the OPERATOR's admin-scoped token
 *   - ANTHROPIC_API_KEY — the platform's billing key
 *
 * i.e. any registered user could exfiltrate both.
 */

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

const SRC = readFileSync("src/lib/hosted-claude-loop.ts", "utf8");
const envBlock = SRC.slice(
  SRC.indexOf("const env: Record<string, string> = {"),
  SRC.indexOf("const exec = getExecutor();")
);

describe("operator PAT is never exposed", () => {
  it("GLUECRON_PAT is not injected into the snippet env", () => {
    expect(envBlock).not.toMatch(/env\.GLUECRON_PAT\s*=/);
    expect(envBlock).not.toMatch(/GLUECRON_PAT:/);
  });

  it("is gone from the whole module, not just relocated", () => {
    const assignments = SRC.match(/env\.GLUECRON_PAT\s*=/g) ?? [];
    expect(assignments.length).toBe(0);
  });
});

describe("platform Anthropic key is opt-in", () => {
  it("is not unconditionally placed in the env", () => {
    // The original bug: a bare property on the object literal.
    expect(envBlock).not.toMatch(/^\s*ANTHROPIC_API_KEY:/m);
  });

  it("requires an explicit operator opt-in flag", () => {
    expect(envBlock).toContain('process.env.HOSTED_LOOPS_PLATFORM_KEY === "1"');
  });

  it("defaults to withholding the key", () => {
    // Guard against the flag being inverted later: absence of the env var
    // must mean no key.
    const gate = envBlock.slice(envBlock.indexOf("HOSTED_LOOPS_PLATFORM_KEY"));
    expect(gate).toContain("env.ANTHROPIC_API_KEY =");
    expect(envBlock.indexOf("HOSTED_LOOPS_PLATFORM_KEY")).toBeLessThan(
      envBlock.indexOf("env.ANTHROPIC_API_KEY =")
    );
  });
});

describe("what the snippet legitimately still gets", () => {
  it("keeps the non-secret loop identifiers", () => {
    expect(envBlock).toContain("GLUECRON_AGENT_ID");
    expect(envBlock).toContain("GLUECRON_LOOP_ID");
    expect(envBlock).toContain("GLUECRON_BASE_URL");
  });
});
