import path from "node:path";
import fg from "fast-glob";
import { type CommandResult, success } from "../../../lib/command-result";
import { readJsonFile } from "../../../lib/parse-json";
import { checkCompatRange } from "./compat-range";
import { checkErpKitVersion } from "./erp-kit-version";
import { ManifestSchema, type VersionFinding, type WorkspacePackage } from "./shared";
import { checkSkillsVersion } from "./skills-version";

export interface MeasureVersionsResult {
  status: "ok" | "violations";
  violationCount: number;
  findings: VersionFinding[];
}

async function discoverWorkspacePackages(cwd: string, appsRoot: string, modulesRoot: string) {
  const patterns = [
    "package.json",
    `${appsRoot}/*/backend/package.json`,
    `${appsRoot}/*/frontend/package.json`,
    `${modulesRoot}/*/package.json`,
  ];
  const matches = await fg(patterns, {
    cwd,
    onlyFiles: true,
    ignore: ["**/node_modules/**"],
  });
  const packages: WorkspacePackage[] = [];
  const findings: VersionFinding[] = [];
  for (const relativePath of matches) {
    const result = readJsonFile(path.join(cwd, relativePath), ManifestSchema, relativePath);
    if (result.ok) {
      packages.push({ relativePath, manifest: result.data });
    } else {
      findings.push({
        severity: "error",
        check: "manifest-parse",
        subject: relativePath,
        message: result.error,
      });
    }
  }
  return { packages, findings };
}

export async function collectMeasureVersions({
  appsRoot,
  modulesRoot,
  cwd,
  installedVersion,
}: {
  appsRoot: string;
  modulesRoot: string;
  cwd: string;
  installedVersion: string;
}): Promise<MeasureVersionsResult> {
  const { packages, findings } = await discoverWorkspacePackages(cwd, appsRoot, modulesRoot);
  findings.push(
    ...checkCompatRange(packages),
    ...checkErpKitVersion(packages, installedVersion),
    ...(await checkSkillsVersion(cwd, installedVersion)),
  );

  const violationCount = findings.filter((f) => f.severity !== "info").length;
  return {
    status: violationCount === 0 ? "ok" : "violations",
    violationCount,
    findings,
  };
}

export async function runInternalMeasureVersions(config: {
  appsRoot: string;
  modulesRoot: string;
  cwd: string;
  installedVersion: string;
}): Promise<CommandResult> {
  const result = await collectMeasureVersions(config);
  console.log(JSON.stringify(result, null, 2));
  return success();
}
