import { checkIncidentsReadiness } from "./bootstrap";
import { loadIncidentsConnection } from "./connection";
import { decodeIncidentRunnerRequest } from "./incident-launcher";
import { createKanboardClient } from "./kanboard-client";
import { IncidentMutationStore } from "./incident-mutation-store";
import { recordIncidentInitializationFailure, runIncident } from "./incident-runner";
import { createIncidentsProvider } from "./provider";
import { createIncidentStatusWriter } from "./status-writer";
import { IncidentStatusStore } from "./status-store";
import { incidentMutationDbFile, incidentStatusDbFile } from "../paths";

const encoded = process.argv[2];
if (!encoded) throw new Error("missing incident runner request");
const request = decodeIncidentRunnerRequest(encoded);
const store = new IncidentStatusStore(incidentStatusDbFile());
const mutationStore = new IncidentMutationStore(incidentMutationDbFile());
let writer: ReturnType<typeof createIncidentStatusWriter>;
let resolveIncident: (incidentId: string, artifact: string, summary: string) => Promise<void>;
try {
  const connection = loadIncidentsConnection();
  if (!connection) throw new Error("incidents connection unavailable");
  const client = createKanboardClient({ baseUrl: connection.baseUrl, token: connection.token, fetchImpl: fetch });
  const readiness = await checkIncidentsReadiness(client);
  writer = createIncidentStatusWriter(client, readiness, store);
  const incidents = createIncidentsProvider({ client, recordStatus: writer, mutationStore, workspaceFor: (incidentId) => {
    if (incidentId !== request.incidentId) throw new Error("incident workspace authority mismatch");
    return request.workspace;
  } });
  resolveIncident = async (incidentId, artifact, summary) => { await incidents.resolveIncident(incidentId, artifact, summary); };
} catch (error) {
  try {
    recordIncidentInitializationFailure(request, (update) => store.commit(update));
  } catch (commitError) {
    throw new AggregateError([error, commitError], "incident runner initialization and durable failure recording both failed");
  } finally {
    store.close();
  }
  throw error;
}
try {
  await runIncident(request, { recordStatus: writer, resolveIncident });
} finally {
  store.close();
}
