import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
import {
  CONTROL_PLANE_BOOTSTRAP_ENVIRONMENT_KEYS,
  I1_CONFIGURATION_DEFINITIONS,
} from "@awp/config";

const expectedBootstrapEnvironment = [
  "DATABASE_URL",
  "PORT",
  "AWP_CONTROL_HOST",
  "AWP_OPERATOR_PASSWORD_HASH",
  "AWP_MACHINE_ENROLLMENT_SECRET_ROOT",
  "AWP_CLUSTER_ID",
  "AWP_CLUSTER_NAME",
  "AWP_CLUSTER_API_SERVER_URL",
  "AWP_CLUSTER_K3S_VERSION",
  "AWP_CLUSTER_JOIN_CREDENTIAL_ID",
  "AWP_CLUSTER_JOIN_SECRET_KEY",
  "AWP_MACHINE_SSH_CREDENTIAL_ID",
  "AWP_MACHINE_SSH_CONNECTION_ID",
  "AWP_MACHINE_SSH_SECRET_KEY",
  "AWP_MACHINE_ENROLLMENT_KNOWN_HOSTS_FILE",
  "AWP_MACHINE_ENROLLMENT_KUBECTL_COMMAND",
  "AWP_MACHINE_ENROLLMENT_SSH_PORT",
  "AWP_SUBROUTER_URL",
  "AWP_SUBROUTER_ADMIN_TOKEN_FILE",
  "AWP_SUBROUTER_ACCOUNT_IMPORT_TOKEN_FILE",
  "AWP_CODEX_COMMAND",
  "AWP_FABRO_URL",
  "AWP_FABRO_TOKEN_FILE",
  "AWP_KUBERNETES_API_BASE",
  "AWP_KUBERNETES_TOKEN",
  "AWP_EXECUTION_CALLBACK_SECRET",
  "AWP_EXECUTION_CALLBACK_BASE_URL",
  "AWP_MODEL_GATEWAY_URL",
  "AWP_MODEL_GATEWAY_SIGNING_SECRET_FILE",
  "AWP_SOURCE_REPOSITORY_PATH",
  "AWP_GITHUB_PUBLICATION_TOKEN_FILE",
  "AWP_GITHUB_PUBLICATION_APP_ID",
  "AWP_GITHUB_PUBLICATION_INSTALLATION_ID",
  "AWP_GITHUB_PUBLICATION_APP_PRIVATE_KEY_FILE",
  "AWP_GITHUB_PUBLICATION_REPOSITORY",
  "AWP_SELF_REPOSITORY_URL",
  "AWP_SELF_PROJECT_BOOTSTRAP",
  "AWP_KUBECTL_COMMAND",
  "AWP_DBOS_EXECUTOR_ID",
  "AWP_VISION_FILE",
  "AWP_SELF_REQUIRED_CHECKS",
  "AWP_DEPLOYMENT_MODE",
  "AWP_DEPLOYED_SOURCE_SHA",
  "AWP_DEPLOYED_SOURCE_TREE",
  "AWP_DOGFOOD_NATIVE_ACP_FAIL_AFTER_PROMPT_ON_INITIAL",
  "AWP_AGENT_START_DELAY_SECONDS",
  "AWP_AGENT_PATCH_FIXTURE_MODE",
] as const;

describe("I1 configuration pain invariants", () => {
  it("bootstrap-config-allowlist-is-closed", () => {
    expect(CONTROL_PLANE_BOOTSTRAP_ENVIRONMENT_KEYS).toEqual(expectedBootstrapEnvironment);
  });

  it("config-authority-is-postgres-only", () => {
    expect(I1_CONFIGURATION_DEFINITIONS.map((definition) => definition.key)).toEqual([
      "execution.enabled",
      "execution.defaultModel",
      "execution.nativeAcpEnabled",
      "workspace.namespace",
      "workspace.image",
    ]);
    const server = readFileSync("apps/control-plane/src/server.ts", "utf8");
    const directEnvironmentReads = new Set(
      [...server.matchAll(/(?:process\.env|env)\.(AWP_[A-Z0-9_]+)/g)].map((match) => match[1]!),
    );
    for (const key of directEnvironmentReads) {
      expect(CONTROL_PLANE_BOOTSTRAP_ENVIRONMENT_KEYS).toContain(key);
    }
    for (const legacy of [
      "AWP_AGENT_ACCOUNT_ID",
      "AWP_AGENT_MODEL",
      "AWP_FORCE_FIRST_ATTEMPT_FAILURE",
      "AWP_WORKSPACE_STORAGE",
      "AWP_NATIVE_ACP_ENABLED",
      "AWP_WORKSPACE_NAMESPACE",
      "AWP_WORKSPACE_IMAGE",
    ]) {
      expect(server).not.toContain(`process.env.${legacy}`);
      expect(server).not.toContain(`env.${legacy}`);
    }
    expect(server).toContain("ConfigurationAuthorityService");
    expect(server).toContain("await configuration.ensureDefinitions()");
    expect(server).toContain("await configuration.resolveSystemWorkspaceConfiguration()");
    const webServer = readFileSync("apps/web/src/server.ts", "utf8");
    const projectRenderer = readFileSync("apps/web/src/render-project.ts", "utf8");
    const systemRenderer = readFileSync("apps/web/src/render-system-settings.ts", "utf8");
    const webClient = readFileSync("apps/web/src/client.ts", "utf8");
    expect(webServer).toContain("/internal/configuration/definitions");
    expect(webServer).toContain("/internal/configuration/effective/");
    expect(projectRenderer).toContain("data-${scopeType}-settings");
    expect(projectRenderer).toContain("data-project-config");
    expect(projectRenderer).toContain("data-system-config");
    expect(projectRenderer).toContain("Deployment-managed for I1");
    expect(systemRenderer).toContain('renderConfigurationPanel("system", "system"');
    expect(systemRenderer).toContain("Global defaults inherited by Projects");
    expect(webServer).toContain('const settingsMatch = url.pathname === "/settings"');
    expect(webClient).toContain("HTMLInputElement | HTMLSelectElement");
    expect(webClient).toContain("[data-project-config],[data-system-config]");
    expect(webClient).toContain("/api/internal/configuration/overrides");
    expect(webClient).toContain('method: "PUT"');
    expect(webClient).toContain('method: "DELETE"');
    const deploy = readFileSync("infra/dogfood/deploy-debian3.sh", "utf8");
    expect(deploy).not.toContain("AWP_NATIVE_ACP_ENABLED=1\n");
    expect(deploy).not.toContain("AWP_WORKSPACE_NAMESPACE=awp-workspaces\n");
    expect(deploy).not.toContain("AWP_WORKSPACE_IMAGE=$AGENT_RUNNER_IMAGE\n");
    expect(deploy).toContain("AWP_CONFIG_NATIVE_ACP_ENABLED=1");
    expect(deploy).toContain("apps/control-plane/dist/configure-i1-runtime.js");
    expect(deploy).toContain(
      "AWP_CODEX_COMMAND=$APP_ROOT/repo/apps/control-plane/node_modules/.bin/codex",
    );
    expect(deploy).not.toContain("/home/user/.claude/bin/codex");
    const stopServices = deploy.indexOf(
      "systemctl --user stop awp-dogfood-web.service awp-dogfood-control-plane.service",
    );
    const restartPostgres = deploy.indexOf("systemctl --user restart awp-dogfood-postgres.service");
    const importConfiguration = deploy.indexOf(
      '"$MISE_BIN" x node@24 -- node apps/control-plane/dist/configure-i1-runtime.js',
    );
    const swapSource = deploy.indexOf('mv "$APP_ROOT/repo.next" "$APP_ROOT/repo"');
    const restartControlPlane = deploy.indexOf(
      "systemctl --user restart awp-dogfood-control-plane.service",
    );
    expect(stopServices).toBeGreaterThan(-1);
    expect(restartPostgres).toBeGreaterThan(stopServices);
    expect(importConfiguration).toBeGreaterThan(restartPostgres);
    expect(swapSource).toBeGreaterThan(importConfiguration);
    expect(restartControlPlane).toBeGreaterThan(swapSource);
    const persistence = readFileSync("packages/persistence/src/unit-of-work.ts", "utf8");
    expect(persistence).toContain(".onConflictDoNothing({ target: configurationDefinitions.key })");
  });

  it("workspace-config-is-projection", () => {
    const lifecycle = readFileSync("packages/application/src/golive.ts", "utf8");
    expect(lifecycle).toContain("resolveProjectExecutionInTransaction");
    expect(lifecycle).toContain("effectiveModel");
    expect(lifecycle).toContain("model: effectiveModel");
    expect(lifecycle).not.toContain("AWP_AGENT_MODEL");
    const server = readFileSync("apps/control-plane/src/server.ts", "utf8");
    expect(server).toContain('image: "postgres:workspace.image"');
    expect(server).not.toContain("process.env.AWP_WORKSPACE_IMAGE");
    expect(server).not.toContain("process.env.AWP_WORKSPACE_NAMESPACE");
    const workspaceResources = readFileSync(
      "packages/providers/workspace-kubernetes/src/resources.ts",
      "utf8",
    );
    expect(workspaceResources).toContain('"awp.dev/configuration-authority": "postgresql"');
    expect(workspaceResources).toContain('"awp.dev/configuration-projection": "read-only"');
    expect(workspaceResources).toContain('"awp.dev/configuration-projection-expires-with"');
    expect(workspaceResources).toContain("readOnlyRootFilesystem: true");
  });

  it("every-mechanism-has-an-off-switch", () => {
    const execution = I1_CONFIGURATION_DEFINITIONS.find(
      (definition) => definition.key === "execution.enabled",
    );
    expect(execution).toMatchObject({ defaultValue: true, mutable: true });
    expect(execution?.allowedScopes).toContain("project");
  });
});
