package com.correx.core.events.events

import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/** Overall verdict of a semantic (LLM) review over a stage's produced files. */
enum class ReviewVerdict { PASS, WARN, FAIL }

/** Severity of a single review finding, high→low. */
enum class ReviewSeverity { CRITICAL, MAJOR, MINOR, NIT }

/**
 * One PR-comment-style finding from the semantic reviewer (Gate 3). A finding is a proposal, not a
 * fact — [confidence] is the reviewer's own 0..1 self-estimate and [correctness] marks findings that
 * claim the code is *wrong* (deterministically re-confirmable) vs. merely *suboptimal* (a smell /
 * style / architecture opinion that can never block on its own).
 */
@Serializable
data class ReviewFinding(
    val severity: ReviewSeverity,
    /** Reviewer self-estimated confidence, 0.0..1.0. */
    val confidence: Double,
    /** Short category slug, e.g. "correctness", "smell", "architecture", "naming". */
    val category: String,
    /** Workspace-relative file (optionally :line) the finding anchors to. */
    val target: String,
    /** What is wrong / suboptimal. Kept bounded by the producer. */
    val message: String,
    /** Suggested fix, when the reviewer offers one. */
    val suggestedFix: String? = null,
    /** True = claims the code is incorrect (confirmable); false = suboptimal opinion (never blocks). */
    val correctness: Boolean = false,
)

/**
 * Environment observation (invariant #9): the semantic reviewer's findings over a stage's produced
 * files, captured at the moment the stage completed. The reviewer is advisory — it reads the actual
 * FileWritten manifest (never blind context) and its findings surface to the operator regardless of
 * verdict. A [ReviewVerdict.FAIL] carrying a high-confidence correctness finding can block the stage
 * retryably, but only until the review-block retry budget is spent, after which findings surface
 * without blocking. Replay reads these recorded facts and never re-runs the reviewer.
 */
@Serializable
@SerialName("ReviewFindingsRaised")
data class ReviewFindingsRaisedEvent(
    val sessionId: SessionId,
    val stageId: StageId,
    val verdict: ReviewVerdict,
    val findings: List<ReviewFinding>,
    /** True when this review's FAIL verdict blocked the stage (fed back for a fix); false = advisory. */
    val blocked: Boolean = false,
) : EventPayload
