//! Stage-1 / selfhost CLI environment helpers (SSOT).

use crate::config::env::{env_bool, warn_alias_once};

/// Primary toggle: enable Stage-1 stub routing.
pub fn enabled() -> bool {
    env_bool("NYASH_USE_STAGE1_CLI")
        || env_bool("HAKO_STAGE1_ENABLE")
        || env_bool("HAKO_EMIT_PROGRAM_JSON")
        || env_bool("HAKO_EMIT_MIR_JSON")
}

/// Recursion guard when Stage-1 stub calls back into the runner.
pub fn child_invocation() -> bool {
    env_bool("NYASH_STAGE1_CLI_CHILD")
}

/// Stage-1 mode hint (emit-program / emit-mir / run).
pub fn mode() -> Option<String> {
    if let Some(m) = std::env::var("HAKO_STAGE1_MODE")
        .ok()
        .or_else(|| std::env::var("NYASH_STAGE1_MODE").ok())
    {
        let trimmed = m.trim();
        if !trimmed.is_empty() {
            return Some(trimmed.to_ascii_lowercase().replace('_', "-"));
        }
    }
    if std::env::var("HAKO_EMIT_PROGRAM_JSON").ok().as_deref() == Some("1") {
        return Some("emit-program".into());
    }
    if std::env::var("HAKO_EMIT_MIR_JSON").ok().as_deref() == Some("1") {
        return Some("emit-mir".into());
    }
    if std::env::var("STAGE1_EMIT_PROGRAM_JSON").ok().as_deref() == Some("1") {
        return Some("emit-program".into());
    }
    if std::env::var("STAGE1_EMIT_MIR_JSON").ok().as_deref() == Some("1") {
        return Some("emit-mir".into());
    }
    if enabled() {
        return Some("run".into());
    }
    None
}

/// True when Stage-1 should emit Program(JSON v0).
pub fn emit_program_json() -> bool {
    matches!(
        mode().as_deref(),
        Some("emit-program" | "emit-program-json")
    )
}

/// True when Stage-1 should emit MIR(JSON).
pub fn emit_mir_json() -> bool {
    matches!(mode().as_deref(), Some("emit-mir" | "emit-mir-json"))
}

/// Input source path passed to Stage-1 stub (aliases included).
pub fn input_path() -> Option<String> {
    std::env::var("HAKO_STAGE1_INPUT")
        .ok()
        .or_else(|| std::env::var("NYASH_STAGE1_INPUT").ok())
        .or_else(|| std::env::var("STAGE1_SOURCE").ok())
        .or_else(|| std::env::var("STAGE1_INPUT").ok())
}

/// Program(JSON v0) path for Stage-1 emit-mir mode (aliases included).
pub fn program_json_path() -> Option<String> {
    std::env::var("HAKO_STAGE1_PROGRAM_JSON")
        .ok()
        .or_else(|| std::env::var("NYASH_STAGE1_PROGRAM_JSON").ok())
        .or_else(|| std::env::var("STAGE1_PROGRAM_JSON").ok())
}

/// Backend hint for Stage-1 run mode (aliases included).
pub fn backend_hint() -> Option<String> {
    std::env::var("HAKO_STAGE1_BACKEND")
        .ok()
        .or_else(|| std::env::var("NYASH_STAGE1_BACKEND").ok())
        .or_else(|| std::env::var("STAGE1_BACKEND").ok())
}

/// Optional override for Stage-1 CLI entry path.
pub fn entry_override() -> Option<String> {
    std::env::var("STAGE1_CLI_ENTRY")
        .ok()
        .or_else(|| std::env::var("HAKORUNE_STAGE1_ENTRY").ok())
}

/// Optional Stage-1 child args (passed through to stub).
pub fn child_args_env() -> Option<String> {
    std::env::var("NYASH_SCRIPT_ARGS_JSON").ok()
}

/// Stage-1 debug flag (verbose child stderr).
pub fn debug() -> bool {
    std::env::var("STAGE1_CLI_DEBUG").ok().as_deref() == Some("1")
}

/// Alias compatibility for backends (warn once).
pub fn backend_alias_warned() -> Option<String> {
    if let Some(be) = std::env::var("STAGE1_BACKEND").ok() {
        warn_alias_once("STAGE1_BACKEND", "NYASH_STAGE1_BACKEND");
        return Some(be);
    }
    None
}
