'use strict';

/**
 * Claude adapter — appends to CLAUDE.md under a marker line.
 * Never overwrites human-written content above the marker.
 *
 * Contract:
 *   format(context, opts?) → string
 *   outputPath(cwd) → string
 *   write(context, cwd, opts?) → void   (handles append logic)
 */

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

const name = 'claude';

const MARKER = '\n\n## Auto-generated signatures\n<!-- Updated by gen-context.js -->\n';
const ALLOWLIST_MARKER = '<!-- sigmap-bash-allowlist -->';

const ALLOWLIST_BLOCK = [
  '## Bash allowlist',
  '',
  ALLOWLIST_MARKER,
  '',
  'The following sigmap commands are pre-approved — Claude Code will not prompt for confirmation:',
  '',
  '```json',
  JSON.stringify({
    permissions: {
      allow: [
        'Bash(sigmap ask*)',
        'Bash(sigmap validate*)',
        'Bash(sigmap judge*)',
        'Bash(sigmap weights*)',
        'Bash(sigmap history*)',
        'Bash(sigmap --query*)',
        'Bash(sigmap --diff*)',
        'Bash(sigmap --health*)',
        'Bash(sigmap --coverage*)',
        'Bash(node gen-context.js*)',
      ],
    },
  }, null, 2),
  '```',
  '',
  'Add the `permissions.allow` array above to `.claude/settings.json` to activate.',
  '',
].join('\n');

/**
 * Format context suited for CLAUDE.md.
 * @param {string} context - Raw signature context string
 * @param {object} [opts]
 * @param {string} [opts.version] - SigMap version string
 * @returns {string}
 */
function format(context, opts = {}) {
  if (!context || typeof context !== 'string') return '';
  const version   = opts.version || 'unknown';
  const timestamp = new Date().toISOString();
  const meta      = _confidenceMeta(opts);
  return [
    '## SigMap',
    '- Before searching for files, run `sigmap ask "<query>"` — ranks by TF-IDF relevance',
    '- After config changes, run `sigmap validate` to confirm coverage',
    '- To verify answer groundedness, run `sigmap judge --response <file> --context CLAUDE.md`',
    '- For PR-scoped context, run `sigmap --diff`',
    '',
    `<!-- Generated by SigMap v${version} — ${timestamp} -->`,
    meta,
    '',
    context,
  ].join('\n');
}

function _confidenceMeta(opts) {
  const parts = [`version=${opts.version || 'unknown'}`];
  if (opts.confidence)    parts.push(`confidence=${opts.confidence}`);
  if (opts.coverage != null) parts.push(`coverage=${opts.coverage}%`);
  if (opts.dropped  != null) parts.push(`dropped=${opts.dropped}`);
  if (opts.commit)        parts.push(`commit=${opts.commit}`);
  return `<!-- sigmap: ${parts.join(' ')} -->`;
}

/**
 * Return the output file path for this adapter.
 * @param {string} cwd - Project root
 * @returns {string}
 */
function outputPath(cwd) {
  return path.join(cwd, 'CLAUDE.md');
}

/**
 * Write signatures into CLAUDE.md using the append-under-marker strategy.
 * Human content above the marker is never touched.
 * @param {string} context - Raw signature context string
 * @param {string} cwd - Project root
 * @param {object} [opts]
 */
function write(context, cwd, opts = {}) {
  const filePath = outputPath(cwd);
  let existing = '';
  if (fs.existsSync(filePath)) {
    existing = fs.readFileSync(filePath, 'utf8');
  }
  const formatted = format(context, opts);
  const markerIdx = existing.indexOf('## Auto-generated signatures');
  let newContent;
  if (markerIdx !== -1) {
    newContent = existing.slice(0, markerIdx) + MARKER.trimStart() + formatted;
  } else {
    newContent = existing + MARKER + formatted;
  }

  // Inject ## Bash allowlist above the sig marker if not already present
  if (!newContent.includes(ALLOWLIST_MARKER)) {
    const sigMarkerPos = newContent.indexOf('## Auto-generated signatures');
    if (sigMarkerPos !== -1) {
      newContent = newContent.slice(0, sigMarkerPos) + ALLOWLIST_BLOCK + '\n' + newContent.slice(sigMarkerPos);
    } else {
      newContent = ALLOWLIST_BLOCK + '\n' + newContent;
    }
  }

  fs.writeFileSync(filePath, newContent, 'utf8');
}

module.exports = { name, format, outputPath, write };
