import fs from "fs";
import {
  cleanupOrphanedLocalInfrastructure,
  destroyRuntimeDatabase,
  destroyServiceDatabaseCache,
  isDatabaseStateDir,
  showServiceDatabaseStatus,
} from "../database/index.mjs";
import { cleanupRuns, formatRunSummary } from "./lifecycle.mjs";
import { printRunStatus } from "./readiness.mjs";
import { findGraphDirsForService, findRuntimeStateDirs } from "./state.mjs";
import { printStateDir } from "./state-io.mjs";

export async function destroy(config) {
  await cleanupRuns(config.productDir, { includeActive: true });
  const roots = new Set([
    config.stateDir,
    ...findGraphDirsForService(config.productDir, config.name),
  ]);

  for (const rootDir of roots) {
    if (!fs.existsSync(rootDir)) continue;
    const runtimeStateDirs = findRuntimeStateDirs(rootDir, isDatabaseStateDir);
    for (const stateDir of runtimeStateDirs) {
      await destroyRuntimeDatabase({
        productDir: config.productDir,
        stateDir,
      });
    }
    fs.rmSync(rootDir, { recursive: true, force: true });
  }

  await destroyServiceDatabaseCache(config.productDir, config.name);
  await cleanupOrphanedLocalInfrastructure(config.productDir);
}

export function showStatus(config) {
  printRunStatus(config.productDir);
  const graphDirs = findGraphDirsForService(config.productDir, config.name);
  const hasDirectState = fs.existsSync(config.stateDir);
  const hasGraphState = graphDirs.length > 0;

  if (!hasDirectState && !hasGraphState) {
    console.log("No state — run tests first.");
  } else {
    if (hasDirectState) {
      console.log("  service-state/");
      printStateDir(config.stateDir, "    ");
    }
    for (const graphDir of graphDirs) {
      console.log(`  graph-state/${graphDir.split("/").at(-1)}/`);
      printStateDir(graphDir, "    ");
    }
  }

  showServiceDatabaseStatus(config.productDir, config.name);
}

export async function cleanup(productDir) {
  const summary = await cleanupRuns(productDir, { includeActive: false });
  if (summary.cleaned.length === 0 && summary.skippedActive.length === 0) {
    console.log("No stale runs to clean.");
    return;
  }

  for (const manifest of summary.cleaned) {
    console.log(`Cleaned stale run ${formatRunSummary(manifest)}`);
  }
  for (const manifest of summary.skippedActive) {
    console.log(`Active run still present: ${formatRunSummary(manifest)}`);
  }
}
