import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { controlPlaneServiceRuntime, killAndRestartControlPlane } from "./control-plane-service.js";
import { approvedJourneyEnvironment, requiredEnvironment } from "./exact-journey.js";

const databaseUrl = requiredEnvironment(process.env, "AWP_TEST_POSTGRES_URL");
const runtime = controlPlaneServiceRuntime();
const { factoryRunId } = approvedJourneyEnvironment();

function psql(statement: string): string {
  return execFileSync("psql", [databaseUrl, "-At", "-c", statement], {
    encoding: "utf8",
  }).trim();
}

function snapshot(): unknown {
  const query = `
    select json_build_object(
      'projects', coalesce((select json_agg(row_to_json(p) order by p.id) from (
        select id, name, repository_url, status, revision from projects
      ) p), '[]'::json),
      'plans', coalesce((select json_agg(row_to_json(p) order by p.id) from (
        select id, project_id, title, status, revision from plans
      ) p), '[]'::json),
      'tasks', coalesce((select json_agg(row_to_json(t) order by t.id) from (
        select id, project_id, plan_revision_id, title, position, status, dependency_ids, goal_ids, revision from tasks
      ) t), '[]'::json),
      'factory_runs', coalesce((select json_agg(row_to_json(f) order by f.id) from (
        select id, project_id, plan_revision_id, task_id, status, reason, revision from factory_runs
      ) f), '[]'::json)
    );
  `;
  return JSON.parse(psql(query)) as unknown;
}

assert.equal(
  psql(`select status from factory_runs where id='${factoryRunId.replaceAll("'", "''")}'`),
  "completed",
  "AC-03 must restart only after the exact owner FactoryRun is terminal",
);
assert.equal(
  psql("select count(*) from agent_runs where status in ('queued','active','waiting')"),
  "0",
  "AC-03 requires no in-flight AgentRun work",
);

const before = snapshot();
const beforeObject = before as { factory_runs?: unknown[] };
assert.ok(
  (beforeObject.factory_runs?.length ?? 0) > 0,
  "snapshot requires durable FactoryRun state",
);

const restart = await killAndRestartControlPlane(runtime);
const after = snapshot();
assert.deepEqual(after, before);

process.stdout.write(
  `AC-03 PASS: deployed control plane ${runtime.service} restarted ${restart.priorPid}->${restart.replacementPid}; Project, Plan, Task, and FactoryRun projections remained identical\n`,
);
