import fs from "fs";
import path from "path";
import { execa } from "execa";
import { buildExecutionEnv } from "../runner/template.mjs";
import {
  collectConfiguredInputs,
  runConfiguredSteps,
} from "../runner/template-steps.mjs";

export async function runTemplateStage(config, stageName, databaseUrl) {
  const steps = config.testkit.database?.template?.[stageName] || [];
  if (steps.length === 0) return;

  const env = {
    ...buildExecutionEnv(config, {}, process.env),
    DATABASE_URL: databaseUrl,
  };

  await runConfiguredSteps({
    config,
    steps,
    env,
    labelPrefix: `template:${stageName}`,
  });
}

export function collectTemplateInputs(productDir, template = {}) {
  const steps = ["migrate", "seed", "verify"].flatMap((stageName) => template[stageName] || []);
  return collectConfiguredInputs(productDir, {
    inputs: template.inputs || [],
    steps,
  });
}

export async function captureTemplateSnapshot(config, outputPath, databaseUrl) {
  const templateDbUrl = databaseUrl;
  const absoluteOutputPath = path.resolve(config.productDir, outputPath);
  fs.mkdirSync(path.dirname(absoluteOutputPath), { recursive: true });

  await execa(
    "pg_dump",
    [
      "--schema-only",
      "--no-owner",
      "--no-privileges",
      "--file",
      absoluteOutputPath,
      templateDbUrl,
    ],
    {
      cwd: config.productDir,
      env: {
        ...buildExecutionEnv(config, {}, process.env),
        DATABASE_URL: templateDbUrl,
      },
      stdio: "inherit",
    }
  );

  sanitizeSnapshotFile(absoluteOutputPath);
  return absoluteOutputPath;
}

function sanitizeSnapshotFile(filePath) {
  const dump = fs.readFileSync(filePath, "utf8");
  const sanitized = dump
    .split("\n")
    .filter((line) => line.trim() !== "SET transaction_timeout = 0;")
    .join("\n");

  if (sanitized !== dump) {
    fs.writeFileSync(filePath, sanitized);
  }
}
