// Copyright (c) 2026 defconxt. All rights reserved.
// Licensed under AGPL-3.0 — see LICENSE file for details.

/**
 * JSON-based compliance framework loader.
 *
 * Loads framework control data from data/compliance/*.json files.
 * These JSON files are the canonical source — generated by extracting
 * from controls.js and independently versionable.
 *
 * @module api/compliance-data
 */

import { readFileSync, readdirSync, existsSync } from 'node:fs';
import { join, dirname, resolve, basename } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));

/**
 * Find the data/compliance directory.
 * @returns {string|null}
 */
function findComplianceDataDir() {
  // Walk up from cli/lib/api/ to find data/compliance/
  let dir = resolve(__dirname, '..', '..', '..');
  for (let i = 0; i < 5; i++) {
    const candidate = join(dir, 'data', 'compliance');
    if (existsSync(candidate)) return candidate;
    dir = dirname(dir);
  }
  return null;
}

/**
 * Load all compliance frameworks from JSON files.
 * @returns {Map<string, Array<{id: string, name: string, category: string}>>}
 */
export function loadAllFrameworks() {
  const dir = findComplianceDataDir();
  if (!dir) return new Map();

  const frameworks = new Map();
  for (const file of readdirSync(dir).sort()) {
    if (!file.endsWith('.json')) continue;
    try {
      const data = JSON.parse(readFileSync(join(dir, file), 'utf-8'));
      const name = basename(file, '.json');
      frameworks.set(name, data);
    } catch { /* skip corrupt files */ }
  }
  return frameworks;
}

/**
 * Load a single framework by name.
 * @param {string} name - Framework name (e.g. 'nist_800_53', 'pci_dss')
 * @returns {Array<{id: string, name: string, category: string}>|null}
 */
export function loadFramework(name) {
  const dir = findComplianceDataDir();
  if (!dir) return null;
  const file = join(dir, `${name}.json`);
  if (!existsSync(file)) return null;
  try {
    return JSON.parse(readFileSync(file, 'utf-8'));
  } catch {
    return null;
  }
}

/**
 * List available framework names.
 * @returns {string[]}
 */
export function listFrameworks() {
  const dir = findComplianceDataDir();
  if (!dir) return [];
  return readdirSync(dir)
    .filter(f => f.endsWith('.json'))
    .map(f => basename(f, '.json'))
    .sort();
}
