//! VM and backend-related environment flags
//!
//! This module groups all VM execution and backend selection flags.
//! Use this for IDE autocomplete to discover VM/backend flags easily.

use super::{env_bool, env_flag, warn_alias_once};

// ---- LLVM harness toggle (llvmlite) ----
pub fn llvm_use_harness() -> bool {
    // Phase 15: デフォルトON（LLVMバックエンドはPythonハーネス使用）
    // NYASH_LLVM_USE_HARNESS=0 で明示的に無効化可能
    match std::env::var("NYASH_LLVM_USE_HARNESS").ok().as_deref() {
        Some("0") | Some("false") | Some("off") => false,
        _ => true, // デフォルト: ON（ハーネス使用）
    }
}

/// LLVM opt level (primary: NYASH_LLVM_OPT_LEVEL; alias: HAKO_LLVM_OPT_LEVEL)
/// Returns string level (e.g., "0", "1", ...). Default: "0" when unset.
pub fn llvm_opt_level() -> String {
    if let Some(v) = std::env::var("NYASH_LLVM_OPT_LEVEL").ok() {
        return v;
    }
    if let Some(v) = std::env::var("HAKO_LLVM_OPT_LEVEL").ok() {
        warn_alias_once("HAKO_LLVM_OPT_LEVEL", "NYASH_LLVM_OPT_LEVEL");
        return v;
    }
    "0".to_string()
}

pub fn vm_use_py() -> bool {
    std::env::var("NYASH_VM_USE_PY").ok().as_deref() == Some("1")
}

pub fn pipe_use_pyvm() -> bool {
    std::env::var("NYASH_PIPE_USE_PYVM").ok().as_deref() == Some("1")
}

/// (Deprecated) use dispatch-based VM route; currently disabled.
pub fn vm_use_dispatch() -> bool {
    false
}

/// Force VM fallback interpreter route (dev-only escape hatch).
pub fn vm_use_fallback() -> bool {
    std::env::var("NYASH_VM_USE_FALLBACK").ok().as_deref() == Some("1")
}

/// Trace VM route selection decisions.
pub fn vm_route_trace() -> bool {
    std::env::var("NYASH_VM_ROUTE_TRACE").ok().as_deref() == Some("1")
}

/// Policy: allow VM to fallback-dispatch user Instance BoxCall (dev only by default).
/// - prod: default false (disallow)
/// - dev/ci: default true (allow, with WARN)
/// Override with NYASH_VM_USER_INSTANCE_BOXCALL={0|1}
pub fn vm_allow_user_instance_boxcall() -> bool {
    match std::env::var("NYASH_VM_USER_INSTANCE_BOXCALL")
        .ok()
        .as_deref()
        .map(|v| v.to_ascii_lowercase())
    {
        Some(ref s) if s == "0" || s == "false" || s == "off" => false,
        Some(ref s) if s == "1" || s == "true" || s == "on" => true,
        _ => !using_is_prod(),
    }
}

// Import using profile functions needed for vm_allow_user_instance_boxcall
fn using_is_prod() -> bool {
    using_profile().eq_ignore_ascii_case("prod")
}

fn using_profile() -> String {
    std::env::var("NYASH_USING_PROFILE").unwrap_or_else(|_| "dev".to_string())
}

pub fn nyvm_core_wrapper() -> bool {
    env_flag("HAKO_NYVM_CORE")
        .or_else(|| env_flag("NYASH_NYVM_CORE"))
        .unwrap_or(false)
}

pub fn nyvm_bridge_inject_singleton() -> bool {
    env_flag("HAKO_BRIDGE_INJECT_SINGLETON")
        .or_else(|| env_flag("NYASH_BRIDGE_INJECT_SINGLETON"))
        .unwrap_or(false)
}

pub fn nyvm_bridge_early_phi_materialize() -> bool {
    env_flag("HAKO_BRIDGE_EARLY_PHI_MATERIALIZE")
        .or_else(|| env_flag("NYASH_BRIDGE_EARLY_PHI_MATERIALIZE"))
        .unwrap_or(false)
}

pub fn nyvm_v1_downconvert() -> bool {
    env_flag("HAKO_NYVM_V1_DOWNCONVERT")
        .or_else(|| env_flag("NYASH_NYVM_V1_DOWNCONVERT"))
        .unwrap_or(false)
}

/// Gate‑C(Core) route request (primary: NYASH_GATE_C_CORE; alias: HAKO_GATE_C_CORE)
pub fn gate_c_core() -> bool {
    if env_bool("NYASH_GATE_C_CORE") {
        return true;
    }
    if env_bool("HAKO_GATE_C_CORE") {
        warn_alias_once("HAKO_GATE_C_CORE", "NYASH_GATE_C_CORE");
        return true;
    }
    false
}

/// Gate‑C(Core) strict OOB handling: when enabled, any observed OOB tag
/// (emitted by runtime during ArrayBox get/set with HAKO_OOB_STRICT=1) should
/// cause non‑zero exit at the end of JSON→VM execution.
pub fn oob_strict_fail() -> bool {
    env_flag("HAKO_OOB_STRICT_FAIL")
        .or_else(|| env_flag("NYASH_OOB_STRICT_FAIL"))
        .unwrap_or(false)
}

/// Primary verification route: return true when Hakorune VM is requested as primary.
/// Accepts HAKO_VERIFY_PRIMARY=hakovm (preferred) or legacy HAKO_ROUTE_HAKOVM=1 (deprecated, warns).
pub fn verify_primary_is_hakovm() -> bool {
    if std::env::var("HAKO_VERIFY_PRIMARY").ok().as_deref() == Some("hakovm") {
        return true;
    }
    if env_bool("HAKO_ROUTE_HAKOVM") {
        warn_alias_once("HAKO_ROUTE_HAKOVM", "HAKO_VERIFY_PRIMARY=hakovm");
        return true;
    }
    false
}
