import { afterEach, expect, test } from "bun:test";
import { handleRpcRequest } from "../../../../../packages/dev-server/src/rpc-dispatch.ts";
import catalogServiceImplementation from "../../admin/app/services/catalog.ts";
import { GET } from "../app/api/product.ts";

const secret = process.env.WRNEXUS_RPC_SECRET;
const app = process.env.WRNEXUS_APP_NAME;
const origins = process.env.WRNEXUS_INTERNAL_ORIGINS;
afterEach(() => {
  if (secret === undefined) delete process.env.WRNEXUS_RPC_SECRET;
  else process.env.WRNEXUS_RPC_SECRET = secret;
  if (app === undefined) delete process.env.WRNEXUS_APP_NAME;
  else process.env.WRNEXUS_APP_NAME = app;
  if (origins === undefined) delete process.env.WRNEXUS_INTERNAL_ORIGINS;
  else process.env.WRNEXUS_INTERNAL_ORIGINS = origins;
});

function startAdmin() {
  return Bun.serve({
    port: 0,
    hostname: "127.0.0.1",
    async fetch(request) {
      return (
        (await handleRpcRequest(
          request,
          new URL(request.url),
          new Map([["catalog", catalogServiceImplementation]]),
        )) ?? new Response("Not found", { status: 404 })
      );
    },
  });
}

test("web calls admin through private RPC when permitted", async () => {
  process.env.WRNEXUS_RPC_SECRET = "test-rpc-secret-at-least-32-chars-long";
  process.env.WRNEXUS_APP_NAME = "web";
  const server = startAdmin();
  process.env.WRNEXUS_INTERNAL_ORIGINS = JSON.stringify({
    admin: `http://127.0.0.1:${server.port}`,
  });
  try {
    const response = await GET({
      req: new Request("http://web.test/api/product?sku=starter"),
      user: { id: "demo-user" },
      locals: {},
    } as never);
    expect(await response.json()).toEqual({
      product: { sku: "starter", name: "WRNexus Starter", priceCents: 4900 },
    });
  } finally {
    server.stop(true);
  }
});

test("web returns 403 when admin denies catalog:read", async () => {
  process.env.WRNEXUS_RPC_SECRET = "test-rpc-secret-at-least-32-chars-long";
  process.env.WRNEXUS_APP_NAME = "web";
  const server = startAdmin();
  process.env.WRNEXUS_INTERNAL_ORIGINS = JSON.stringify({
    admin: `http://127.0.0.1:${server.port}`,
  });
  try {
    const response = await GET({
      req: new Request("http://web.test/api/product"),
      user: { id: "not-allowed" },
      locals: {},
    } as never);
    expect(response.status).toBe(403);
    expect(await response.json()).toEqual({ error: "Forbidden" });
  } finally {
    server.stop(true);
  }
});
