import { existsSync, readFileSync, readdirSync } from "node:fs";
import { resolve } from "node:path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { GET as getSolvency } from "../../../repos/theloopbreaker-site/app/api/v3/protocol/solvency/route";
import { GET as getStatus } from "../../../repos/theloopbreaker-site/app/api/v3/protocol/status/route";
import { GET as getMandate } from "../../../repos/theloopbreaker-site/app/api/v3/mandate/[mandateHash]/route";
import { POST as createPartnershipBond } from "../../../repos/theloopbreaker-site/app/api/v3/x402/actions/create-partnership-bond/route";
import { GET as getDiscovery } from "../../../repos/theloopbreaker-site/app/api/v3/x402/discovery/route";
import { GET as getChallengeStatus } from "../../../repos/theloopbreaker-site/app/api/v3/x402/challenge-status/route";
import { GET as getSolanaHealth } from "../../../repos/theloopbreaker-site/app/api/v3/solana/health/route";
import { GET as getReceipt } from "../../../repos/theloopbreaker-site/app/api/v3/x402/receipts/[requestId]/route";
import { V3_X402_RELEASE_ENV, V3_X402_RELEASE_VALUE } from "../../../repos/theloopbreaker-site/app/api/v3/x402/_lib/release";

const root = resolve(import.meta.dirname, "../../..");
const site = resolve(root, "repos/theloopbreaker-site");
const originalFlag = process.env[V3_X402_RELEASE_ENV];
const hash = `0x${"12".repeat(32)}`;
function filesBelow(directory: string): string[] {
  if (!existsSync(directory)) return [];
  return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() ? filesBelow(resolve(directory, entry.name)) : [resolve(directory, entry.name)]);
}
beforeAll(() => { delete process.env[V3_X402_RELEASE_ENV]; });
afterAll(() => { if (originalFlag === undefined) delete process.env[V3_X402_RELEASE_ENV]; else process.env[V3_X402_RELEASE_ENV] = originalFlag; });

describe("V3 x402 no-payment harness", () => {
  it("keeps every materialized V3 route release-closed by default", async () => {
    const responses = [
      getDiscovery(), getStatus(), getSolvency(), getChallengeStatus(), getSolanaHealth(),
      await getMandate(new Request(`https://theloopbreaker.com/api/v3/mandate/${hash}`), { params: { mandateHash: hash } }),
      createPartnershipBond(new Request("https://theloopbreaker.com/api/v3/x402/actions/create-partnership-bond", { method: "POST" })),
      await getReceipt(new Request("https://theloopbreaker.com/api/v3/x402/receipts/request-1"), { params: { requestId: "request-1" } }),
    ];
    for (const response of responses) {
      expect(response.status).toBe(503);
      expect(await response.json()).toMatchObject({ code: "v3_x402_release_gate_closed", releaseMode: "disabled" });
    }
  });

  it("permits only static discovery/readiness under the exact flag and never emits a payment instruction", async () => {
    process.env[V3_X402_RELEASE_ENV] = V3_X402_RELEASE_VALUE;
    for (const response of [getStatus(), getSolvency()]) {
      expect(response.status).toBe(503);
      expect(response.headers.get("payment-required")).toBeNull();
      expect(response.headers.get("payment-response")).toBeNull();
    }
    for (const response of [getDiscovery(), getChallengeStatus(), getSolanaHealth()]) {
      expect(response.status).toBe(200);
      expect(response.headers.get("payment-required")).toBeNull();
      expect(response.headers.get("payment-response")).toBeNull();
    }
    const paymentAttempt = createPartnershipBond(new Request("https://theloopbreaker.com/api/v3/x402/actions/create-partnership-bond", {
      method: "POST", headers: { "PAYMENT-SIGNATURE": "untrusted-bytes" }, body: "untrusted-body",
    }));
    expect(paymentAttempt.status).toBe(503);
    expect(await paymentAttempt.json()).toMatchObject({ schema: "vaultfire.v3.x402.retirement.v1", requestInspected: false, bodyParsed: false, executable: false });
  });

  it("keeps V2 handlers independent of V3 release/payment code", () => {
    const v2Files = filesBelow(resolve(site, "app/api/x402")).filter((path) => path.endsWith(".ts") && !path.includes("/app/api/x402/v3/"));
    expect(v2Files.length).toBeGreaterThan(80);
    for (const file of v2Files) expect(readFileSync(file, "utf8"), file).not.toMatch(/app\/api\/v3|api\/v3\/x402|V3_X402_RELEASE/);
  });
});
