"use strict";

const fs = require("fs");
const path = require("path");

const BUNDLE = require("./boilerplate-bundle");

const DEFAULT_SCOPE = [
  /^src\/utils\/locators\//,
  /^src\/utils\/storage-state\//,
];

const REQUIRED_SUPPORT_FILES = [
  "src/config/environment.ts",
  "src/utils/helpers/Logger.ts",
  "src/utils/ai-assistant/AISelfHealing.ts",
];

function matchesScope(relPath, scope = DEFAULT_SCOPE) {
  return scope.some((re) => re.test(relPath));
}

function detectFrameworkDrift(rootDir, scope = DEFAULT_SCOPE) {
  const locDir = path.join(rootDir, "src", "utils", "locators");
  if (!fs.existsSync(locDir)) return null;

  let drift = 0;
  let missing = 0;
  let total = 0;
  for (const [relPath, content] of Object.entries(BUNDLE)) {
    if (!matchesScope(relPath, scope)) continue;
    if (relPath.endsWith(".gitkeep")) continue;
    total++;

    const absPath = path.join(rootDir, relPath);
    if (!fs.existsSync(absPath)) {
      missing++;
      continue;
    }

    try {
      const onDisk = fs.readFileSync(absPath, "utf-8");
      if (onDisk !== content) drift++;
    } catch {
      drift++;
    }
  }

  return { drift, missing, total };
}

function hasUtilsAlias(rootDir) {
  const tsconfigPath = path.join(rootDir, "tsconfig.json");
  if (!fs.existsSync(tsconfigPath)) return false;

  try {
    const tsconfig = fs.readFileSync(tsconfigPath, "utf-8");
    return /"@utils\/\*"\s*:\s*\[\s*"src\/utils\/\*"\s*\]/m.test(tsconfig);
  } catch {
    return false;
  }
}

function checkFrameworkUpgradeCompatibility(rootDir) {
  const missingSupportFiles = REQUIRED_SUPPORT_FILES.filter(
    (relPath) => !fs.existsSync(path.join(rootDir, relPath)),
  );
  const utilsAliasConfigured = hasUtilsAlias(rootDir);

  const issues = [];
  if (missingSupportFiles.length) {
    issues.push(
      `Missing support files: ${missingSupportFiles.join(", ")}`,
    );
  }
  if (!utilsAliasConfigured) {
    issues.push(
      'Missing tsconfig path alias: "@utils/*" -> "src/utils/*"',
    );
  }

  return {
    ok: issues.length === 0,
    issues,
    missingSupportFiles,
    utilsAliasConfigured,
  };
}

function formatCompatibilityIssues(report) {
  return report.issues.map((issue) => `  - ${issue}`).join("\n");
}

module.exports = {
  DEFAULT_SCOPE,
  checkFrameworkUpgradeCompatibility,
  detectFrameworkDrift,
  formatCompatibilityIssues,
  matchesScope,
};