package com.correx.core.transitions.graph

/**
 * Per-stage execution-gate scope (staged-verification design §2) — the closed set a planner picks
 * from to say how far the project should be runnable after this stage. Resolves at runtime to a
 * concrete command drawn from the bound project profile's command aliases, so the command itself
 * stays stack-specific and operator-owned while the *scope* is a fixed vocabulary the planner can't
 * invent.
 *
 * [commandAlias] names the `[commands]` alias to run for this scope (null = no gate). A
 * toolchain-specific command is stored as `<toolchain>.<alias>` in the replay-bound profile map;
 * this corresponds to TOML such as `[commands.node]`. The resolver prefers that scoped command and
 * falls back to the flat alias for existing profiles.
 * NONE → nothing (early stages where the project is not yet runnable), MODULE → typecheck,
 * PROJECT → build, TESTS → test. A stage whose profile lacks the alias skips the gate with a warning
 * rather than failing — the vocabulary degrades safely when the operator hasn't configured commands.
 */
enum class BuildExpectation(val commandAlias: String?) {
    NONE(null),
    MODULE("typecheck"),
    PROJECT("build"),
    TESTS("test"),
    ;

    /**
     * Resolves this gate's command from a profile snapshot. The profile remains a flat map in the
     * event vocabulary, so nested TOML command tables are represented by dotted keys such as
     * `node.build`. This makes the toolchain choice replayable without changing session events.
     */
    fun commandFor(profileCommands: Map<String, String>, toolchain: String?): String? {
        val alias = commandAlias ?: return null
        return toolchain?.let { profileCommands["$it.$alias"] } ?: profileCommands[alias]
    }

    companion object {
        /** Parses a plan's `build_expectation` string; null for an unrecognized value so the compiler rejects it. */
        fun fromPlan(raw: String?): BuildExpectation? = when (raw?.trim()?.lowercase()) {
            null, "", "none" -> NONE
            "module" -> MODULE
            "project" -> PROJECT
            "tests", "test" -> TESTS
            else -> null
        }
    }
}
