/**
 * Agent Runtime Layer — Adapters
 *
 * PR-35 Part D：适配器层，解耦 Runtime 与具体质量系统实现。
 *
 * 设计原则：
 *   - Runtime 不直接依赖 checklist/baseline/gate 具体实现
 *   - 每个 Adapter 提供统一接口
 *   - 支持替换/模拟（测试友好）
 *   - 纯函数适配，无副作用
 *
 * @module agent-runtime/adapters
 */

import { createRisk, createGateDecision, createCertificationResult, createObservation, GATE_DECISION } from "./domain.mjs";

// ═══════════════════════════════════════════════════════
// Adapter Interface (contract, not enforced)
//
//   Each adapter is a function: (context, ...args) => result
//
//   ChecklistAdapter:        (ctx) => { status, blockers, warnings, ... }
//   BaselineAdapter:         (ctx, baseline, candidate) => { status, changes, blockers, warnings }
//   GateAdapter:             (ctx, {checklist, baselineCompare}) => { status, decision, ... }
//   CertificationAdapter:    (ctx, {task, steps, checklist, baseline, gate, risks}) => { tier, score, ... }
//   ReportingAdapter:        (ctx, {task, taskResult}) => string (markdown)
//   ArtifactAdapter:         (ctx, artifact) => { id, stored, ... }
// ═══════════════════════════════════════════════════════

// ─── Checklist Adapter ────────────────────────────────

/**
 * 创建 Checklist 适配器。
 *
 * @param {object} opts
 * @param {function} opts.evaluate  — 实际 checklist 函数: (input) => result
 * @param {function} [opts.mapInput] — 将 Runtime 上下文映射为 checklist 输入
 * @returns {function} adapter(ctx) => checklist result
 */
export function createChecklistAdapter({ evaluate, mapInput }) {
  if (typeof evaluate !== "function") {
    throw new TypeError("ChecklistAdapter requires an `evaluate` function");
  }

  return function checklistAdapter(ctx) {
    try {
      const input = mapInput ? mapInput(ctx) : ctx;
      const result = evaluate(input);
      return _normalizeChecklistResult(result);
    } catch (err) {
      return _checklistErrorResult(err);
    }
  };
}

/** 使用现有 PR-13 评价函数的内置适配器 */
export function builtinChecklistAdapter(evaluateReleaseCandidate) {
  return createChecklistAdapter({
    evaluate: evaluateReleaseCandidate,
    mapInput: (ctx) => ({
      readiness: { status: ctx.readinessStatus || "pass", safeToReplace: ctx.safeToReplace !== false },
      rolloutStage: { action: ctx.rolloutAction || "promote", currentStage: ctx.currentStage ?? 100 },
      rollbackReport: { recommendation: ctx.rollbackRecommendation || "keep_enabled" },
      circuitBreaker: { state: ctx.circuitState || "closed" },
      testSummary: {
        total: ctx.testTotal ?? ctx.steps?.length ?? 1,
        failed: ctx.testFailed ?? 0,
        regressions: ctx.testRegressions ?? 0,
      },
    }),
  });
}

function _normalizeChecklistResult(raw) {
  if (!raw || typeof raw !== "object") return _checklistErrorResult(new Error("Empty checklist result"));
  return {
    status: raw.status || "unknown",
    confidence: raw.confidence ?? 0,
    releaseCandidate: raw.releaseCandidate ?? (raw.status === "pass"),
    blockers: Array.isArray(raw.blockers) ? [...raw.blockers] : [],
    warnings: Array.isArray(raw.warnings) ? [...raw.warnings] : [],
    checks: raw.checks || {},
    recommendation: raw.recommendation || "",
    _raw: raw,
  };
}

function _checklistErrorResult(err) {
  return {
    status: "fail",
    confidence: 0,
    releaseCandidate: false,
    blockers: [`Checklist adapter error: ${err.message}`],
    warnings: [],
    checks: {},
    recommendation: "Checklist evaluation failed. Fix adapter configuration.",
    _error: err.message,
  };
}

// ─── Baseline Adapter ────────────────────────────────

/**
 * 创建 Baseline 适配器。
 *
 * @param {object} opts
 * @param {function} opts.compare — 实际 baseline 比较函数: (baseline, candidate, options?) => result
 * @returns {function} adapter(ctx, baseline, candidate) => baseline result
 */
export function createBaselineAdapter({ compare }) {
  if (typeof compare !== "function") {
    throw new TypeError("BaselineAdapter requires a `compare` function");
  }

  return function baselineAdapter(ctx, baseline, candidate) {
    try {
      if (!baseline || !candidate) {
        return _baselineMissingResult(baseline, candidate);
      }
      const result = compare(baseline, candidate, ctx.baselineOptions);
      return _normalizeBaselineResult(result);
    } catch (err) {
      return _baselineErrorResult(err);
    }
  };
}

/** 使用现有 PR-16 比较函数的内置适配器 */
export function builtinBaselineAdapter(compareReleaseCandidateBaseline) {
  return createBaselineAdapter({ compare: compareReleaseCandidateBaseline });
}

function _normalizeBaselineResult(raw) {
  if (!raw || typeof raw !== "object") return _baselineErrorResult(new Error("Empty baseline result"));
  return {
    status: raw.status || "unknown",
    changes: Array.isArray(raw.changes) ? [...raw.changes] : [],
    blockers: Array.isArray(raw.blockers) ? [...raw.blockers] : [],
    warnings: Array.isArray(raw.warnings) ? [...raw.warnings] : [],
    _raw: raw,
  };
}

function _baselineMissingResult(baseline, candidate) {
  return {
    status: "warn",
    changes: [],
    blockers: [],
    warnings: [`Baseline${!baseline ? "" : " candidate"} data missing — comparison skipped.`],
    _raw: null,
  };
}

function _baselineErrorResult(err) {
  return {
    status: "fail",
    changes: [],
    blockers: [`Baseline adapter error: ${err.message}`],
    warnings: [],
    _error: err.message,
  };
}

// ─── Gate Adapter ────────────────────────────────────

/**
 * 创建 Gate 适配器。
 *
 * @param {object} opts
 * @param {function} opts.evaluate — 实际 gate 函数: (input, options?) => result
 * @returns {function} adapter(ctx, {checklist, baselineCompare}) => gate result
 */
export function createGateAdapter({ evaluate }) {
  if (typeof evaluate !== "function") {
    throw new TypeError("GateAdapter requires an `evaluate` function");
  }

  return function gateAdapter(ctx, { checklist, baselineCompare }) {
    try {
      const input = {
        checklist: checklist?._raw || checklist,
        baselineCompare: baselineCompare?._raw || baselineCompare,
      };
      if (ctx.manualApproval) {
        input.manualApproval = ctx.manualApproval;
      }
      const options = { requireManualApproval: ctx.requireManualApproval || false };
      const result = evaluate(input, options);
      return _normalizeGateResult(result);
    } catch (err) {
      return _gateErrorResult(err);
    }
  };
}

/** 使用现有 PR-17 评价函数的内置适配器 */
export function builtinGateAdapter(evaluateReleaseGate) {
  return createGateAdapter({ evaluate: evaluateReleaseGate });
}

/**
 * Auto-gate：不依赖外部函数，根据 checklist/baseline 结果自动判定。
 * 当未提供 gateFn 时使用。
 */
export function autoGateAdapter(_ctx, { checklist, baselineCompare }) {
  const blockers = [];
  const warnings = [];

  if (checklist) {
    if (checklist.status === "fail") blockers.push("Checklist FAIL — quality checks did not pass");
    else if (checklist.status === "warn") warnings.push("Checklist WARN — quality concerns exist");
    if (Array.isArray(checklist.blockers)) blockers.push(...checklist.blockers.map(b => `[Checklist] ${b}`));
    if (Array.isArray(checklist.warnings)) warnings.push(...checklist.warnings.map(w => `[Checklist] ${w}`));
  }

  if (baselineCompare) {
    if (baselineCompare.status === "fail") blockers.push("Baseline FAIL — structural anomaly detected");
    else if (baselineCompare.status === "warn") warnings.push("Baseline WARN — structural changes noted");
    if (Array.isArray(baselineCompare.blockers)) blockers.push(...baselineCompare.blockers.map(b => `[Baseline] ${b}`));
    if (Array.isArray(baselineCompare.warnings)) warnings.push(...baselineCompare.warnings.map(w => `[Baseline] ${w}`));
  }

  if (blockers.length > 0) {
    return createGateDecision({
      decision: GATE_DECISION.CLOSED,
      blockers, warnings,
      summary: `Gate CLOSED: ${blockers.length} blocker(s), ${warnings.length} warning(s).`,
    });
  }

  return createGateDecision({
    decision: GATE_DECISION.OPEN,
    blockers: [], warnings,
    summary: warnings.length > 0
      ? `Gate OPEN: ${warnings.length} warning(s) — proceed with caution.`
      : "Gate OPEN: all checks passed.",
  });
}

function _normalizeGateResult(raw) {
  if (!raw || typeof raw !== "object") return _gateErrorResult(new Error("Empty gate result"));
  const decision = (raw.decision || raw.status || "CLOSED").toUpperCase();
  return {
    decision: GATE_DECISION[decision] ? decision : GATE_DECISION.CLOSED,
    canRelease: raw.canRelease ?? (decision === "OPEN"),
    blockers: Array.isArray(raw.blockers) ? [...raw.blockers] : [],
    warnings: Array.isArray(raw.warnings) ? [...raw.warnings] : [],
    summary: raw.summary || "",
    _raw: raw,
  };
}

function _gateErrorResult(err) {
  return {
    decision: GATE_DECISION.CLOSED,
    canRelease: false,
    blockers: [`Gate adapter error: ${err.message}`],
    warnings: [],
    summary: "Gate evaluation failed.",
    _error: err.message,
  };
}

// ─── Certification Adapter ──────────────────────────

/**
 * 创建 Certification 适配器。
 *
 * @param {object} opts
 * @param {function} [opts.evaluate] — 自定义认证函数: (ctx) => CertificationResult
 * @returns {function} adapter(ctx) => CertificationResult
 */
export function createCertificationAdapter({ evaluate } = {}) {
  return function certificationAdapter(ctx) {
    try {
      if (evaluate) {
        return evaluate(ctx);
      }
      return _computeCertification(ctx);
    } catch (err) {
      return createCertificationResult({
        tier: "none",
        score: 0,
        failedCriteria: [`Certification error: ${err.message}`],
        recommendation: "Certification evaluation failed.",
      });
    }
  };
}

function _computeCertification({ checklist, baselineCompare, gateDecision, risks = [] }) {
  const passed = [];
  const failed = [];
  let score = 0;

  // Checklist (0–25)
  if (checklist) {
    if (checklist.status === "pass") { score += 25; passed.push("checklist-pass"); }
    else if (checklist.status === "warn") { score += 15; passed.push("checklist-warn"); }
    else { failed.push("checklist-fail"); }
  } else { failed.push("checklist-missing"); }

  // Baseline (0–25)
  if (baselineCompare) {
    if (baselineCompare.status === "pass") { score += 25; passed.push("baseline-pass"); }
    else if (baselineCompare.status === "warn") { score += 15; passed.push("baseline-warn"); }
    else { failed.push("baseline-fail"); }
  } else { failed.push("baseline-missing"); }

  // Gate (0–25)
  if (gateDecision) {
    if (gateDecision.decision === GATE_DECISION.OPEN) { score += 25; passed.push("gate-open"); }
    else { failed.push("gate-closed"); }
  } else { failed.push("gate-missing"); }

  // Risks (0–25)
  const highRisks = risks.filter(r => r.level === "high" || r.level === "critical").length;
  if (highRisks === 0 && risks.length === 0) { score += 25; passed.push("no-risks"); }
  else if (highRisks === 0) { score += 15; passed.push("low-risks-only"); }
  else if (highRisks <= 2) { score += 8; failed.push(`${highRisks}-high-risks`); }
  else { failed.push(`${highRisks}-high-risks`); }

  // 等级
  let tier, recommendation;
  if (score >= 90)      { tier = "platinum"; recommendation = "Exceptional quality. Ready for production."; }
  else if (score >= 75) { tier = "gold";     recommendation = "High quality. Minor improvements suggested."; }
  else if (score >= 60) { tier = "silver";   recommendation = "Acceptable quality. Address warnings."; }
  else if (score >= 40) { tier = "bronze";   recommendation = "Minimum quality met. Improve before release."; }
  else                   { tier = "none";     recommendation = "Quality bar not met. Fix blockers and re-evaluate."; }

  return createCertificationResult({ tier, score, passedCriteria: passed, failedCriteria: failed, recommendation });
}

// ─── Reporting Adapter ──────────────────────────────

/**
 * 创建 Reporting 适配器。
 *
 * @param {object} opts
 * @param {function} opts.generate — 报告生成函数: (task, taskResult) => string
 * @returns {function} adapter(ctx, {task, taskResult}) => string
 */
export function createReportingAdapter({ generate }) {
  if (typeof generate !== "function") {
    throw new TypeError("ReportingAdapter requires a `generate` function");
  }
  return function reportingAdapter(_ctx, { task, taskResult }) {
    try {
      return generate(task, taskResult);
    } catch (err) {
      return `# Report Generation Failed\n\nError: ${err.message}`;
    }
  };
}

// ─── Artifact Adapter ───────────────────────────────

/**
 * 创建 Artifact 适配器。
 *
 * @param {object} opts
 * @param {object} opts.registry — ArtifactRegistry 实例
 * @returns {function} adapter(ctx, artifact) => { id, stored }
 */
export function createArtifactAdapter({ registry }) {
  if (!registry || typeof registry.store !== "function") {
    throw new TypeError("ArtifactAdapter requires a registry with `store` method");
  }
  return function artifactAdapter(_ctx, artifact) {
    try {
      return registry.store(artifact);
    } catch (err) {
      return { id: artifact.id, stored: false, error: err.message };
    }
  };
}

// ═══════════════════════════════════════════════════════
// Runtime Context Factory
// ═══════════════════════════════════════════════════════

/**
 * 创建完整的 Runtime 上下文（注入所有适配器）。
 *
 * @param {object} opts
 * @param {function} opts.checklistAdapter
 * @param {function} opts.baselineAdapter
 * @param {function} opts.gateAdapter
 * @param {function} [opts.certificationAdapter]
 * @param {function} [opts.reportingAdapter]
 * @param {function} [opts.artifactAdapter]
 * @param {object} [opts.baselineData]
 * @param {object} [opts.candidateData]
 * @param {object} [opts.pipelineOptions]
 * @returns {object} RuntimeContext
 */
export function createRuntimeContext({
  checklistAdapter,
  baselineAdapter,
  gateAdapter,
  certificationAdapter,
  reportingAdapter,
  artifactAdapter,
  baselineData = null,
  candidateData = null,
  pipelineOptions = {},
}) {
  return {
    checklistAdapter: checklistAdapter || _defaultChecklistAdapter,
    baselineAdapter: baselineAdapter || _defaultBaselineAdapter,
    gateAdapter: gateAdapter || autoGateAdapter,
    certificationAdapter: certificationAdapter || createCertificationAdapter(),
    reportingAdapter: reportingAdapter || null,
    artifactAdapter: artifactAdapter || null,
    baselineData,
    candidateData,
    pipelineOptions: {
      stopOnStepFailure: true,
      requireGatePass: true,
      minCertScore: 60,
      ...pipelineOptions,
    },
  };
}

// ─── 默认适配器 ────────────────────────────────────

function _defaultChecklistAdapter(_ctx) {
  return { status: "pass", confidence: 100, releaseCandidate: true, blockers: [], warnings: [], checks: {}, recommendation: "Default: checklist passed." };
}

function _defaultBaselineAdapter(_ctx, _baseline, _candidate) {
  return { status: "pass", changes: [], blockers: [], warnings: [] };
}
