/**
 * Release Gate Evaluator — PR-17
 *
 * 整合 RC Checklist、Baseline Compare 和手动审批，输出统一发布门禁决策。
 *
 * 纯函数：无 IO、无 console、无副作用。
 *
 * 决策规则：
 *   OPEN  — checklist pass/warn + baseline pass/warn + 无 blocker + 审批通过（如需）
 *   CLOSED — 任一 fail、有 blocker、审批缺失（如需）、输入无效
 *
 * @module evaluate-release-gate
 */

// ─── 状态常量 ────────────────────────────────────────

export const GATE_OPEN = "open";
export const GATE_CLOSED = "closed";

// ─── 默认选项 ────────────────────────────────────────

const DEFAULT_OPTIONS = {
  /** 是否要求手动审批 */
  requireManualApproval: false,
};

// ─── Gate 评估 ──────────────────────────────────────

/**
 * 评估 Release Gate 状态。
 *
 * @param {object} input
 * @param {object} input.checklist        — RC Checklist 结果 (evaluateReleaseCandidate 输出)
 * @param {object} input.baselineCompare  — Baseline Compare 结果 (compareReleaseCandidateBaseline 输出)
 * @param {object} [input.manualApproval] — 手动审批信息
 * @param {boolean} input.manualApproval.approved
 * @param {string}  [input.manualApproval.approver]
 * @param {string}  [input.manualApproval.reason]
 * @param {object} [options]
 * @param {boolean} [options.requireManualApproval=false]
 * @returns {object} { status, decision, canRelease, blockers, warnings, summary }
 */
export function evaluateReleaseGate(input, options) {
  const opts = { ...DEFAULT_OPTIONS, ...(options || {}) };

  // ── 输入结构验证 ──
  if (!input || typeof input !== "object") {
    return _closed("输入无效 — 不是有效对象", [], {});
  }

  const { checklist, baselineCompare, manualApproval } = input;

  if (!checklist || typeof checklist !== "object") {
    return _closed("输入无效 — checklist 数据缺失或格式错误", [], {});
  }
  if (!baselineCompare || typeof baselineCompare !== "object") {
    return _closed("输入无效 — baselineCompare 数据缺失或格式错误", [], {});
  }

  const blockers = [];
  const warnings = [];

  // 状态只读副本（不修改原对象）
  const checklistStatus = checklist.status || "unknown";
  const baselineStatus = baselineCompare.status || "unknown";

  // ═══════════════════════════════════════════════════
  // 检查 1：Checklist
  // ═══════════════════════════════════════════════════
  if (checklistStatus === "fail") {
    blockers.push("RC Checklist FAIL — 未通过发布前检查");
  } else if (checklistStatus === "unknown") {
    blockers.push("RC Checklist 状态未知 — 无法评估");
  }

  // 继承 checklist 的 blocker/warning
  if (Array.isArray(checklist.blockers)) {
    for (const b of checklist.blockers) {
      blockers.push(`[Checklist] ${b}`);
    }
  }
  if (Array.isArray(checklist.warnings)) {
    for (const w of checklist.warnings) {
      warnings.push(`[Checklist] ${w}`);
    }
  }

  // ═══════════════════════════════════════════════════
  // 检查 2：Baseline Compare
  // ═══════════════════════════════════════════════════
  if (baselineStatus === "fail") {
    blockers.push("Baseline Compare FAIL — 结构规模异常变化");
  } else if (baselineStatus === "unknown") {
    blockers.push("Baseline Compare 状态未知 — 无法评估");
  }

  if (Array.isArray(baselineCompare.blockers)) {
    for (const b of baselineCompare.blockers) {
      blockers.push(`[Baseline] ${b}`);
    }
  }
  if (Array.isArray(baselineCompare.warnings)) {
    for (const w of baselineCompare.warnings) {
      warnings.push(`[Baseline] ${w}`);
    }
  }

  // ═══════════════════════════════════════════════════
  // 检查 3：Manual Approval
  // ═══════════════════════════════════════════════════
  if (opts.requireManualApproval) {
    if (!manualApproval || typeof manualApproval !== "object") {
      blockers.push("手动审批缺失 — requireManualApproval=true 但无审批数据");
    } else if (manualApproval.approved !== true) {
      blockers.push("手动审批未通过 — 需要明确的批准");
    }
  } else {
    // 非强制模式：缺失审批仅提示
    if (!manualApproval || typeof manualApproval !== "object" || manualApproval.approved == null) {
      warnings.push("手动审批数据未提供（非强制，不影响）");
    }
  }

  // ═══════════════════════════════════════════════════
  // 决策
  // ═══════════════════════════════════════════════════
  if (blockers.length > 0) {
    return _closed(summarize(warnings), blockers, warnings, input);
  }

  const summary = "Release gate is OPEN." + (warnings.length > 0 ? ` ${warnings.length} warning(s) present.` : "");

  return {
    status: GATE_OPEN,
    decision: "OPEN",
    canRelease: true,
    blockers: [],
    warnings,
    summary,
  };
}

// ─── 内部工具 ────────────────────────────────────────

/** @returns {object} CLOSED 结果 */
function _closed(reason, blockers, warnings, input) {
  const effectiveBlockers = Array.isArray(blockers) ? blockers : [];
  const effectiveWarnings = Array.isArray(warnings) ? warnings : [];
  // 如果没有具体 blocker，添加通用 reason
  const allBlockers = effectiveBlockers.length > 0
    ? [...effectiveBlockers]
    : [reason];
  return {
    status: GATE_CLOSED,
    decision: "CLOSED",
    canRelease: false,
    blockers: allBlockers,
    warnings: effectiveWarnings,
    summary: `Release gate is CLOSED. ${allBlockers.length} blocker(s), ${effectiveWarnings.length} warning(s).`,
  };
}

function summarize(warnings) {
  if (!warnings || warnings.length === 0) return "Release gate is CLOSED.";
  return `Release gate is CLOSED. ${warnings.length} warning(s) also present.`;
}
