import fs from "fs";
import path from "path";

const GRAPH_METADATA = "graph.json";

export function findRuntimeStateDirs(rootDir, isDatabaseStateDir) {
  const found = [];

  const visit = (dir) => {
    if (!fs.existsSync(dir)) return;
    const entries = fs.readdirSync(dir, { withFileTypes: true });
    if (isDatabaseStateDir(dir)) {
      found.push(dir);
    }

    for (const entry of entries) {
      if (entry.isDirectory()) {
        visit(path.join(dir, entry.name));
      }
    }
  };

  visit(rootDir);
  return found.sort((a, b) => b.length - a.length);
}

export function findGraphDirsForService(productDir, serviceName) {
  const graphsRoot = path.join(productDir, ".testkit", "_graphs");
  if (!fs.existsSync(graphsRoot)) return [];

  const matches = [];
  for (const entry of fs.readdirSync(graphsRoot, { withFileTypes: true })) {
    if (!entry.isDirectory()) continue;
    const graphDir = path.join(graphsRoot, entry.name);
    const metadata = readGraphMetadata(graphDir);
    if (!metadata) continue;
    if ((metadata.runtimeServices || []).includes(serviceName)) {
      matches.push(graphDir);
    }
  }

  return matches.sort();
}

export function writeGraphMetadata(graphDir, graph) {
  fs.mkdirSync(graphDir, { recursive: true });
  const metadata = {
    runtimeServices: graph.runtimeNames,
    assignedTargets: [...graph.assignedTargets].sort(),
    rootService: graph.rootConfig.name,
  };
  fs.writeFileSync(
    path.join(graphDir, GRAPH_METADATA),
    JSON.stringify(metadata, null, 2)
  );
}

export function readGraphMetadata(graphDir) {
  const metadataPath = path.join(graphDir, GRAPH_METADATA);
  if (!fs.existsSync(metadataPath)) return null;

  try {
    return JSON.parse(fs.readFileSync(metadataPath, "utf8"));
  } catch {
    return null;
  }
}

export function normalizePathSeparators(filePath) {
  return filePath.split(path.sep).join("/");
}
