#!/usr/bin/env node
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
import { extname, join } from 'node:path';
import { pathToFileURL } from 'node:url';
import { option, parseArgs } from './ops-utils.mjs';

const forbiddenPatterns = [
  { name: 'TBD', pattern: /\bTBD\b/i },
  { name: 'TODO', pattern: /\bTODO\b/i },
  { name: 'fill-in', pattern: /fill in|fill-in/i },
  { name: 'angle-token', pattern: /<[^>\n]+>/ },
  { name: 'Chinese pending marker', pattern: /待定|占位/ },
];

function usage() {
  return `Usage: node scripts/check-runbook-placeholders.mjs --paths <path> [path...]

Scans Markdown runbooks for unresolved placeholder markers.
`;
}

function collectMarkdownFiles(path) {
  if (!existsSync(path)) {
    throw new Error(`Path not found: ${path}`);
  }

  const stat = statSync(path);
  if (stat.isFile()) return extname(path) === '.md' ? [path] : [];
  if (!stat.isDirectory()) return [];

  const files = [];
  for (const entry of readdirSync(path)) {
    files.push(...collectMarkdownFiles(join(path, entry)));
  }
  return files;
}

function requestedPaths(argv) {
  const args = parseArgs(argv);
  if (args.flags.has('help')) return { help: true, paths: [] };
  const first = option(args, 'paths');
  const paths = [first, ...args.positionals].filter(Boolean);
  if (paths.length === 0) {
    throw new Error('Missing --paths <path> [path...]');
  }
  return { help: false, paths };
}

export function scanFiles(paths) {
  const files = paths.flatMap(collectMarkdownFiles);
  const findings = [];
  for (const file of files) {
    const lines = readFileSync(file, 'utf8').split(/\r?\n/);
    lines.forEach((line, index) => {
      for (const forbidden of forbiddenPatterns) {
        if (forbidden.pattern.test(line)) {
          findings.push(`${file}:${index + 1} ${forbidden.name}: ${line.trim()}`);
        }
      }
    });
  }
  return { files, findings };
}

export async function main(argv = process.argv.slice(2)) {
  const { help, paths } = requestedPaths(argv);
  if (help) {
    process.stdout.write(usage());
    return;
  }

  const { files, findings } = scanFiles(paths);
  if (findings.length > 0) {
    process.stderr.write(`${findings.join('\n')}\n`);
    throw new Error(`Runbook placeholder scan failed: ${findings.length} finding(s)`);
  }

  process.stdout.write(`Runbook placeholder scan passed (${files.length} file(s)).\n`);
}

if (import.meta.url === pathToFileURL(process.argv[1]).href) {
  main().catch((error) => {
    process.stderr.write(`${error.message}\n`);
    process.exit(1);
  });
}

