'use strict';

const fs = require('node:fs');
const path = require('node:path');
const {
  buildChildScopeSection,
  buildPromptEnvelope,
  buildReviewerEnvelope,
  createPromptSection,
  redactPromptContent,
  renderPromptEnvelope,
} = require('./prompt-runtime');

const PROMPT_DIR = path.join(__dirname, '..', 'prompts', 'coding');

function loadPromptText(name) {
  try {
    return fs.readFileSync(path.join(PROMPT_DIR, name), 'utf8').trim();
  } catch {
    return '';
  }
}

/**
 * Provider/model families get a short adaptation block appended to the
 * stable prompt bundle (opencode ships per-model prompt variants for the
 * same reason: instruction-following failure modes differ per family).
 * Blocks live in prompts/coding/<family>.txt and stay short — calibration
 * heuristics, not rule lists.
 */
function providerPromptFamily({ provider = '', model = '' } = {}) {
  const hay = `${provider} ${model}`.toLowerCase();
  if (/deepseek/.test(hay)) return 'deepseek';
  if (/openai|gpt-|codex|\bo[134](-|$)/.test(hay)) return 'gpt';
  if (/google|gemini/.test(hay)) return 'gemini';
  if (/ollama|mlx|lmstudio|qwen|gemma|llama|mistral|phi-/.test(hay)) return 'local';
  return '';
}

function selectPromptFiles({ mode = 'build', provider = '', model = '' } = {}) {
  const files = ['base.txt'];
  if (mode === 'plan') files.push('plan.txt');
  const family = providerPromptFamily({ provider, model });
  if (family) files.push(`${family}.txt`);
  return files;
}

function buildPromptBundle({ body = '', mode = 'build', provider = '', model = '', extraInstructions = [], returnEnvelope = false } = {}) {
  const bundleText = selectPromptFiles({ mode, provider, model })
    .map(loadPromptText)
    .filter(Boolean)
    .join('\n\n');
  const extras = (extraInstructions || [])
    .filter((item) => item?.content)
    .map((item) => createPromptSection({
      id: `instruction:${item.path || 'inline'}`,
      source: item.path || 'extra-instructions',
      content: `## Instruction: ${item.path}\n${item.content}`,
      cacheable: true,
      redactionPolicy: 'secrets',
    }));

  const envelope = buildPromptEnvelope({
    stablePolicy: bundleText,
    toolPolicy: body,
    sections: extras,
    metadata: { mode, provider, model },
  });

  return returnEnvelope ? envelope : renderPromptEnvelope(envelope);
}

module.exports = {
  PROMPT_DIR,
  loadPromptText,
  providerPromptFamily,
  selectPromptFiles,
  buildPromptBundle,
  buildChildScopeSection,
  buildPromptEnvelope,
  buildReviewerEnvelope,
  createPromptSection,
  redactPromptContent,
  renderPromptEnvelope,
};
