/**
 * @internal
 * G5 review-clean — blocking gate for `apt:ship`.
 *
 * Skipped when {task_dir}/review.json is absent (review is optional for some
 * tracks). When it is present, delegates to `parseReview` (DRY with the
 * consistency rule) which normalizes severities + statuses across all the
 * shapes the reviewer skill writes: `fixed: true`, `resolved: true`,
 * `status: "fixed"` (string), and `status: "deferred-*"` variants
 * (BUG-009). Fails if any post-normalization finding is severity
 * critical|major AND status is neither `fixed` nor `deferred`.
 */

import { existsSync, readFileSync } from 'node:fs'
import { join } from 'node:path'
import { parseReview } from '../../consistency/parse-review.mjs'
import { registerGate } from '../registry.mjs'

// Post-normalization severities. `parseReview` maps `warning → major`,
// so the gate keys off `major` here even though the input may carry
// `warning`.
const POST_NORM_BLOCKING = new Set(['critical', 'major'])

const gate = {
	id: 'review-clean',
	description: 'review.json has no unresolved critical/major findings (skipped if absent)',
	severity: 'blocking',
	skills: ['ship'],
	applies_to_profile: (ctx) => ctx.profile === 'full-pipeline',
	async check(ctx) {
		const path = join(ctx.taskDir, 'review.json')
		const inputs = [path]
		if (!existsSync(path)) {
			return {
				status: 'skip',
				reason: 'review.json not present — skipping review-clean',
				inputs,
			}
		}
		let doc
		try {
			doc = JSON.parse(readFileSync(path, 'utf-8'))
		} catch (err) {
			return {
				status: 'fail',
				reason: `review.json does not parse: ${err.message}`,
				inputs,
			}
		}
		// BUG-009: delegate to parseReview so this gate sees the SAME
		// normalized findings the consistency rule does. The pre-fix
		// inline filter only inspected boolean `fixed`/`resolved`, missing
		// `status: "fixed"` strings + `summary.findings_remaining: 0`
		// shapes the reviewer skill writes; this delegation closes that
		// hole and picks up `deferred-*` variants for free.
		const { findings: normalized } = parseReview(doc)
		const unresolved = normalized.filter(
			(f) => POST_NORM_BLOCKING.has(f.severity) && f.status !== 'fixed' && f.status !== 'deferred',
		)
		if (unresolved.length > 0) {
			return {
				status: 'fail',
				reason: `${unresolved.length} unresolved critical/major finding(s) in review.json`,
				evidence: {
					unresolved: unresolved.map((f) => ({
						severity: f.severity,
						id: f.id ?? null,
						title: f.title ?? null,
					})),
				},
				inputs,
			}
		}
		return {
			status: 'pass',
			reason: `review.json has no unresolved critical/major findings (${normalized.length} total)`,
			inputs,
		}
	},
}

registerGate(gate)
export default gate
