//! Global environment configuration aggregator (管理棟)
//!
//! Consolidates NYASH_* environment variables across subsystems and
//! optionally applies overrides from `nyash.toml`.
//!
//! # Modular Organization
//!
//! Environment flags are now organized into focused Box modules:
//! - `joinir_flags` - JoinIR-related flags (30+ functions)
//! - `mir_flags` - MIR-related flags (20+ functions)
//! - `vm_backend_flags` - VM/Backend flags (15+ functions)
//! - `parser_flags` - Parser flags (10+ functions)
//! - `using_flags` - Using/namespace flags (10+ functions)
//! - `verification_flags` - Verification flags (8+ functions)
//! - `selfhost_flags` - Selfhost compiler flags (10+ functions)
//!
//! All functions are re-exported at the top level for backward compatibility.

mod catalog;
pub mod dump;
// Phase 124: hako_check module removed (JoinIR-only consolidation)
// pub mod hako_check;
pub mod joinir_dev;
pub mod stage1;

// New modular organization
mod joinir_flags;
mod mir_flags;
mod parser_flags;
mod selfhost_flags;
mod using_flags;
mod verification_flags;
mod vm_backend_flags;

pub use catalog::{env_vars, AppliesTo, EnvVarMeta};
pub use dump::*;
// Phase 124: hako_check exports removed (JoinIR-only consolidation)
// pub use hako_check::*;
pub use joinir_dev::*;
pub use stage1::*;

// Backward-compatible re-exports (NO BREAKING CHANGES!)
pub use joinir_flags::*;
pub use mir_flags::*;
pub use parser_flags::*;
pub use selfhost_flags::*;
pub use using_flags::*;
pub use verification_flags::*;
pub use vm_backend_flags::*;

use std::collections::BTreeMap;

#[derive(Debug, Clone, Default)]
pub struct NyashEnv {
    // ARCHIVED: JIT-related configuration moved to archive/jit-cranelift/ during Phase 15
    // pub jit: crate::jit::config::JitConfig,
    /// Arbitrary key-value overrides loaded from nyash.toml [env]
    pub overrides: BTreeMap<String, String>,
}

impl NyashEnv {
    pub fn from_env() -> Self {
        Self {
            // ARCHIVED: JIT config during Phase 15
            // jit: crate::jit::config::JitConfig::from_env(),
            overrides: BTreeMap::new(),
        }
    }
    /// Apply current struct values into process environment
    pub fn apply_env(&self) {
        // ARCHIVED: JIT config during Phase 15
        // self.jit.apply_env();
        for (k, v) in &self.overrides {
            std::env::set_var(k, v);
        }
    }
}

// Global current env config (thread-safe)
use once_cell::sync::OnceCell;
use std::collections::HashSet;
use std::sync::Mutex;

static GLOBAL_ENV: OnceCell<std::sync::RwLock<NyashEnv>> = OnceCell::new();
static WARNED_ALIASES: OnceCell<Mutex<HashSet<String>>> = OnceCell::new();

pub fn current() -> NyashEnv {
    if let Some(lock) = GLOBAL_ENV.get() {
        if let Ok(cfg) = lock.read() {
            return cfg.clone();
        }
    }
    NyashEnv::from_env()
}

pub fn set_current(cfg: NyashEnv) {
    if let Some(lock) = GLOBAL_ENV.get() {
        if let Ok(mut w) = lock.write() {
            *w = cfg;
            return;
        }
    }
    let _ = GLOBAL_ENV.set(std::sync::RwLock::new(cfg));
}

/// Load overrides from nyash.toml `[env]` table and apply them to process env.
///
/// Example:
/// [env]
/// NYASH_JIT_THRESHOLD = "1"
/// NYASH_CLI_VERBOSE = "1"
pub fn bootstrap_from_toml_env() {
    // Allow disabling nyash.toml env bootstrapping for isolated smokes/CI
    if std::env::var("NYASH_SKIP_TOML_ENV").ok().as_deref() == Some("1") {
        return;
    }
    // Prefer hakorune.toml, fallback to nyash.toml
    let alt = if std::path::Path::new("hakorune.toml").exists() {
        "hakorune.toml"
    } else {
        "nyash.toml"
    };
    let path = alt;
    let content = match std::fs::read_to_string(path) {
        Ok(s) => s,
        Err(_) => return,
    };
    let Ok(value) = toml::from_str::<toml::Value>(&content) else {
        return;
    };
    let Some(env_tbl) = value.get("env").and_then(|v| v.as_table()) else {
        return;
    };
    let mut overrides: BTreeMap<String, String> = BTreeMap::new();
    for (k, v) in env_tbl {
        if let Some(s) = v.as_str() {
            std::env::set_var(k, s);
            overrides.insert(k.clone(), s.to_string());
        } else if let Some(b) = v.as_bool() {
            let sv = if b { "1" } else { "0" };
            std::env::set_var(k, sv);
            overrides.insert(k.clone(), sv.to_string());
        } else if let Some(n) = v.as_integer() {
            let sv = n.to_string();
            std::env::set_var(k, &sv);
            overrides.insert(k.clone(), sv);
        }
    }
    // Merge into global
    let mut cur = current();
    cur.overrides.extend(overrides);
    set_current(cur);
}

/// Generic boolean env parser: accepts 1/true/on (case-insensitive) as true.
pub fn env_bool(key: &str) -> bool {
    match std::env::var(key).ok() {
        Some(v) => {
            let lv = v.to_ascii_lowercase();
            lv == "1" || lv == "true" || lv == "on"
        }
        None => false,
    }
}

/// Generic boolean env parser with default when unset.
pub fn env_bool_default(key: &str, default: bool) -> bool {
    match std::env::var(key).ok() {
        Some(v) => {
            let lv = v.to_ascii_lowercase();
            lv == "1" || lv == "true" || lv == "on"
        }
        None => default,
    }
}

pub(crate) fn env_flag(var: &str) -> Option<bool> {
    std::env::var(var).ok().map(|v| {
        let lv = v.to_ascii_lowercase();
        lv == "1" || lv == "true" || lv == "on"
    })
}

pub(crate) fn warn_alias_once(alias: &str, primary: &str) {
    let set = WARNED_ALIASES.get_or_init(|| Mutex::new(HashSet::new()));
    if let Ok(mut s) = set.lock() {
        if !s.contains(alias) {
            eprintln!(
                "[deprecate/env] '{}' is deprecated; use '{}'",
                alias, primary
            );
            s.insert(alias.to_string());
        }
    }
}
