import assert from "node:assert/strict";
import { createServer as createHttpServer } from "node:http";
import { test } from "bun:test";

import { createCloudApiServer } from "./server.ts";

const adminActor = { id: "usr_admin", username: "admin", displayName: "Admin", role: "admin", status: "active" };
const userActor = { id: "usr_user", username: "user", displayName: "User", role: "user", status: "active" };

test("provider profile management requires HWLAB admin auth before AgentRun delegation", async () => {
  const calls: unknown[] = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: userActor })
  });
  await listen(server);
  const { port } = server.address() as { port: number };

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles`, { headers: { cookie: "hwlab_session=user" } });
    const body = await response.json();
    assert.equal(response.status, 403);
    assert.equal(body.error.code, "admin_required");
    assert.equal(calls.length, 0);
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

test("provider profile catalog is readable to authenticated non-admin actors and redacts management-only fields", async () => {
  const calls: Array<AgentRunCall> = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: userActor })
  });
  await listen(server);
  const { port } = server.address() as { port: number };

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/provider-profiles`, { headers: { cookie: "hwlab_session=user" } });
    const body = await response.json();
    assert.equal(response.status, 200);
    assert.equal(body.ok, true);
    assert.equal(body.contractVersion, "provider-profile-management-v1");
    assert.equal(body.count, 4);
    const profiles = body.items.map((item: any) => item.profile);
    assert.equal(profiles.includes("deepseek"), true);
    assert.equal(profiles.includes("codex-api"), true);
    assert.equal(profiles.includes("minimax-m3"), true);
    assert.equal(profiles.includes("dsflash-go-cli-example"), true);
    assert.equal(body.items[0].secretRef, undefined);
    assert.equal(body.items[0].credentialHashSuffix, undefined);
    assert.equal(body.items[0].bridge.route, "HWLAB Moon Bridge -> DeepSeek official upstream");
    assert.equal(JSON.stringify(body).includes("auth.json"), false);
    assert.equal(calls[0].method, "GET");
    assert.equal(calls[0].path, "/api/v1/provider-profiles");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-manager-key");
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

test("provider profiles collection delegates to AgentRun, rewrites codex profile, and preserves dynamic slugs", async () => {
  const calls: Array<AgentRunCall> = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: adminActor })
  });
  await listen(server);
  const { port } = server.address() as { port: number };

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles`, { headers: { cookie: "hwlab_session=admin" } });
    const body = await response.json();
    assert.equal(response.status, 200);
    assert.equal(body.ok, true);
    assert.equal(body.contractVersion, "provider-profile-management-v1");
    assert.equal(body.delegation.agentRunHost, "127.0.0.1");
    const profiles = body.items.map((item: any) => item.profile);
    assert.equal(body.count, 4);
    assert.equal(profiles.includes("deepseek"), true);
    assert.equal(profiles.includes("codex-api"), true);
    assert.equal(profiles.includes("minimax-m3"), true);
    assert.equal(profiles.includes("dsflash-go-cli-example"), true);
    assert.equal(body.items[0].bridge.route, "HWLAB Moon Bridge -> DeepSeek official upstream");
    assert.equal(JSON.stringify(body).includes("auth.json"), true);
    assert.equal(JSON.stringify(body).includes("sk-test"), false);
    assert.equal(calls[0].method, "GET");
    assert.equal(calls[0].path, "/api/v1/provider-profiles");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-manager-key");
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

test("provider profile set-key delegates through HWLAB without echoing API key", async () => {
  const calls: Array<AgentRunCall> = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: adminActor, authMethod: "api-key" })
  });
  await listen(server);
  const { port } = server.address() as { port: number };
  const key = "sk-test-provider-secret-123456";

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles/deepseek/credential`, {
      method: "PUT",
      headers: { "content-type": "application/json", authorization: "Bearer hwlab-test" },
      body: JSON.stringify({ apiKey: key })
    });
    const body = await response.json();
    const text = JSON.stringify(body);
    assert.equal(response.status, 200);
    assert.equal(body.ok, true);
    assert.equal(body.status, "updated");
    assert.equal(body.profile, "deepseek");
    assert.equal(body.data.requiresExternalBridgeUpdate, true);
    assert.equal(text.includes(key), false);
    assert.equal(text.includes("Bearer hwlab-test"), false);
    assert.equal(calls[0].method, "PUT");
    assert.equal(calls[0].path, "/api/v1/provider-profiles/deepseek/credential");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-manager-key");
    assert.equal(calls[0].authorization?.includes(key), false);
    assert.equal(calls[0].body.apiKey, key);
    assert.equal(calls[0].body.delegatedBy.system, "hwlab-v02");
    assert.equal(calls[0].body.delegatedBy.userId, "usr_admin");
    assert.equal(calls[0].body.delegatedBy.authMethod, "api-key");
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

test("provider profile management accepts lane-specific AgentRun manager namespace", async () => {
  const calls: Array<{ method?: string; path?: string; host?: string; authorization?: string }> = [];
  const server = createCloudApiServer({
    env: {
      AGENTRUN_MGR_URL: "http://agentrun-mgr.agentrun-v02.svc.cluster.local:8080",
      AGENTRUN_API_KEY: "test-agentrun-key",
      HWLAB_ACCESS_CONTROL_REQUIRED: "1"
    },
    fetchImpl: async (url: string, init: any = {}) => {
      const parsed = new URL(url);
      calls.push({ method: init.method, path: parsed.pathname, host: parsed.hostname, authorization: init.headers?.authorization });
      return new Response(JSON.stringify({ ok: true, data: { items: [], count: 0, valuesPrinted: false }, valuesPrinted: false }), { status: 200 });
    },
    accessController: fakeAccessController({ actor: adminActor })
  });
  await listen(server);
  const { port } = server.address() as { port: number };

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles`, { headers: { cookie: "hwlab_session=admin" } });
    const body = await response.json();
    assert.equal(response.status, 200);
    assert.equal(body.ok, true);
    assert.equal(calls[0].method, "GET");
    assert.equal(calls[0].host, "agentrun-mgr.agentrun-v02.svc.cluster.local");
    assert.equal(calls[0].path, "/api/v1/provider-profiles");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-key");
    assert.equal(JSON.stringify(body).includes("test-agentrun-key"), false);
  } finally {
    await close(server);
  }
});

test("provider profile auth-json delegates through HWLAB without echoing auth json", async () => {
  const calls: Array<AgentRunCall> = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: adminActor, authMethod: "api-key" })
  });
  await listen(server);
  const { port } = server.address() as { port: number };
  const authJson = `${JSON.stringify({ OPENAI_API_KEY: "sk-test-provider-secret-123456" })}\n`;

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles/hy/credential`, {
      method: "PUT",
      headers: { "content-type": "application/json", authorization: "Bearer hwlab-test" },
      body: JSON.stringify({ authJson })
    });
    const body = await response.json();
    const text = JSON.stringify(body);
    assert.equal(response.status, 200);
    assert.equal(body.ok, true);
    assert.equal(body.status, "updated");
    assert.equal(body.profile, "hy");
    assert.equal(text.includes("OPENAI_API_KEY"), false);
    assert.equal(text.includes("sk-test-provider-secret-123456"), false);
    assert.equal(calls[0].method, "PUT");
    assert.equal(calls[0].path, "/api/v1/provider-profiles/hy/credential");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-manager-key");
    assert.equal(calls[0].body.authJson, authJson);
    assert.equal(calls[0].body.apiKey, undefined);
    assert.equal(calls[0].body.delegatedBy.system, "hwlab-v02");
    assert.equal(calls[0].body.delegatedBy.authMethod, "api-key");
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

test("provider profile config reads and writes config.toml through AgentRun", async () => {
  const calls: Array<AgentRunCall> = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: adminActor })
  });
  await listen(server);
  const { port } = server.address() as { port: number };
  const configToml = 'model = "deepseek-chat"\nbase_url = "http://bridge/v1"\n';

  try {
    const read = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles/deepseek/config`, { headers: { cookie: "hwlab_session=admin" } });
    const readBody = await read.json();
    assert.equal(read.status, 200);
    assert.equal(readBody.ok, true);
    assert.equal(readBody.profile, "deepseek");
    assert.equal(readBody.data.configToml, configToml);
    assert.equal(readBody.data.configTomlPrinted, true);
    assert.equal(JSON.stringify(readBody).includes("sk-test"), false);

    const write = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles/deepseek/config`, {
      method: "PUT",
      headers: { "content-type": "application/json", cookie: "hwlab_session=admin" },
      body: JSON.stringify({ configToml: `${configToml}# edited\n` })
    });
    const writeBody = await write.json();
    assert.equal(write.status, 200);
    assert.equal(writeBody.status, "updated");
    assert.equal(JSON.stringify(writeBody).includes("# edited"), false);
    assert.equal(calls[0].method, "GET");
    assert.equal(calls[0].path, "/api/v1/provider-profiles/deepseek/config");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-manager-key");
    assert.equal(calls[1].method, "PUT");
    assert.equal(calls[1].path, "/api/v1/provider-profiles/deepseek/config");
    assert.equal(calls[1].authorization, "Bearer test-agentrun-manager-key");
    assert.equal(calls[1].body.configToml, `${configToml}# edited\n`);
    assert.equal(calls[1].body.delegatedBy.system, "hwlab-v02");
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

test("provider profile remove delegates through HWLAB and preserves redaction", async () => {
  const calls: Array<AgentRunCall> = [];
  const agentRunServer = await startAgentRunServer(calls);
  const { port: agentRunPort } = agentRunServer.address() as { port: number };
  const server = createCloudApiServer({
    env: testEnv(agentRunPort),
    accessController: fakeAccessController({ actor: adminActor, authMethod: "api-key" })
  });
  await listen(server);
  const { port } = server.address() as { port: number };

  try {
    const response = await fetch(`http://127.0.0.1:${port}/v1/admin/provider-profiles/deepseek`, {
      method: "DELETE",
      headers: { authorization: "Bearer hwlab-test" }
    });
    const body = await response.json();
    assert.equal(response.status, 200);
    assert.equal(body.ok, true);
    assert.equal(body.status, "removed");
    assert.equal(body.profile, "deepseek");
    assert.equal(body.data.removed, true);
    assert.equal(body.data.builtinCapabilityRetained, true);
    assert.equal(JSON.stringify(body).includes("sk-test"), false);
    assert.equal(calls[0].method, "DELETE");
    assert.equal(calls[0].path, "/api/v1/provider-profiles/deepseek");
    assert.equal(calls[0].authorization, "Bearer test-agentrun-manager-key");
    assert.equal(calls[0].body, null);
  } finally {
    await close(server);
    await close(agentRunServer);
  }
});

function testEnv(port: number) {
  return {
    HWLAB_CODE_AGENT_AGENTRUN_MGR_URL: `http://127.0.0.1:${port}`,
    AGENTRUN_API_KEY: "test-agentrun-manager-key",
    HWLAB_PROVIDER_PROFILE_AGENTRUN_ALLOW_NON_K3S_URL: "1",
    HWLAB_ACCESS_CONTROL_REQUIRED: "1"
  };
}

type AgentRunCall = { method?: string; path?: string; body?: any; authorization?: string };

function fakeAccessController({ actor, authMethod = "web-session" }: { actor: any; authMethod?: string }) {
  return {
    required: true,
    async authenticate(request: any, { required = true } = {}) {
      const hasAuth = Boolean(request.headers?.cookie || request.headers?.authorization);
      if (!hasAuth && required) return { ok: false, status: 401, error: { code: "auth_required", message: "Authentication is required" } };
      return { ok: true, actor, session: { id: "ses_test", userId: actor.id }, authMethod };
    },
    async handleAuthRoute() { throw new Error("not used"); },
    async handleUserRoute() { throw new Error("not used"); },
    async handleAccessStatusRoute() { throw new Error("not used"); },
    async handleSetupRoute() { throw new Error("not used"); },
    async handleAdminRoute() { throw new Error("provider profile route should bypass generic admin route"); },
    configureCodeAgentWorkspaceContext() {}
  };
}

async function startAgentRunServer(calls: Array<AgentRunCall>) {
  const server = createHttpServer(async (request, response) => {
    const url = new URL(request.url || "/", "http://127.0.0.1");
    const chunks = [];
    for await (const chunk of request) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
    const body = chunks.length ? JSON.parse(Buffer.concat(chunks).toString("utf8")) : null;
    calls.push({ method: request.method, path: url.pathname, body, authorization: request.headers.authorization });
    response.writeHead(200, { "content-type": "application/json" });
    if (request.method === "GET" && url.pathname === "/api/v1/provider-profiles") {
      response.end(`${JSON.stringify({ ok: true, traceId: "trc_profiles", data: { items: [profile("deepseek"), profile("codex"), profile("minimax-m3"), profile("dsflash-go-cli-example")], count: 4, valuesPrinted: false } })}\n`);
      return;
    }
    if (request.method === "PUT" && url.pathname === "/api/v1/provider-profiles/deepseek/credential") {
      response.end(`${JSON.stringify({ ok: true, traceId: "trc_set_key", data: { action: "provider-profile-credential-updated", mutation: true, profile: "deepseek", configured: true, secretRef: { namespace: "agentrun-v01", name: "agentrun-v01-provider-deepseek", keys: ["auth.json", "config.toml"] }, credentialHashSuffix: "abc12345", configHashSuffix: "def67890", updatedAt: "2026-06-05T08:00:00.000Z", requiresExternalBridgeUpdate: true, valuesPrinted: false } })}\n`);
      return;
    }
    if (request.method === "PUT" && url.pathname === "/api/v1/provider-profiles/hy/credential") {
      response.end(`${JSON.stringify({ ok: true, traceId: "trc_set_auth_json", data: { action: "provider-profile-credential-updated", mutation: true, profile: "hy", configured: true, credentialSource: "auth-json", secretRef: { namespace: "agentrun-v01", name: "agentrun-v01-provider-hy", keys: ["auth.json", "config.toml"] }, credentialHashSuffix: "1234abcd", configHashSuffix: "def67890", updatedAt: "2026-06-05T08:00:00.000Z", valuesPrinted: false } })}\n`);
      return;
    }
    if (request.method === "GET" && url.pathname === "/api/v1/provider-profiles/deepseek/config") {
      response.end(`${JSON.stringify({ ok: true, traceId: "trc_config", data: { action: "provider-profile-config", profile: "deepseek", configured: true, secretRef: { namespace: "agentrun-v01", name: "agentrun-v01-provider-deepseek", keys: ["auth.json", "config.toml"] }, credentialHashSuffix: "abc12345", configHashSuffix: "def67890", updatedAt: "2026-06-05T08:00:00.000Z", configToml: 'model = "deepseek-chat"\nbase_url = "http://bridge/v1"\n', configTomlPrinted: true, credentialValuesPrinted: false, valuesPrinted: false } })}\n`);
      return;
    }
    if (request.method === "PUT" && url.pathname === "/api/v1/provider-profiles/deepseek/config") {
      response.end(`${JSON.stringify({ ok: true, traceId: "trc_set_config", data: { action: "provider-profile-config-updated", mutation: true, profile: "deepseek", configured: true, secretRef: { namespace: "agentrun-v01", name: "agentrun-v01-provider-deepseek", keys: ["auth.json", "config.toml"] }, credentialHashSuffix: "abc12345", configHashSuffix: "fedcba98", updatedAt: "2026-06-05T08:01:00.000Z", valuesPrinted: false } })}\n`);
      return;
    }
    if (request.method === "DELETE" && url.pathname === "/api/v1/provider-profiles/deepseek") {
      response.end(`${JSON.stringify({ ok: true, traceId: "trc_remove", data: { action: "provider-profile-removed", mutation: true, profile: "deepseek", configured: false, removed: true, builtinCapabilityRetained: true, secretRef: { namespace: "agentrun-v01", name: "agentrun-v01-provider-deepseek", keys: ["auth.json", "config.toml"] }, deletedResourceVersion: "rv-removed", credentialHashSuffix: "abc12345", configHashSuffix: "def67890", updatedAt: "2026-06-05T08:02:00.000Z", valuesPrinted: false } })}\n`);
      return;
    }
    response.end(`${JSON.stringify({ ok: false, error: { code: "unexpected", message: `${request.method} ${url.pathname}` } })}\n`);
  });
  await listen(server);
  return server;
}

function profile(name: string) {
  return {
    profile: name,
    backendKind: name,
    configured: true,
    secretRef: { namespace: "agentrun-v01", name: `agentrun-v01-provider-${name}`, keys: ["auth.json", "config.toml"] },
    credentialHashSuffix: "abc12345",
    configHashSuffix: "def67890",
    updatedAt: "2026-06-05T08:00:00.000Z",
    valuesPrinted: false
  };
}

function listen(server: any) {
  return new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
}

function close(server: any) {
  return new Promise<void>((resolve, reject) => server.close((error: Error | undefined) => (error ? reject(error) : resolve())));
}
