//! A3S Box Core - Foundational Types and Abstractions
//!
//! This module provides the foundational types, traits, and abstractions
//! used across the A3S Box MicroVM runtime.

pub mod audit;
pub mod compose;
pub mod config;
pub mod dns;
pub mod env;
pub mod error;
pub mod event;
pub mod exec;
pub mod fs_atomic;
pub mod log;
pub mod network;
pub mod operator;
pub mod platform;
pub mod port;
pub mod pty;
pub mod scale;
pub mod security;
pub mod snapshot;
pub mod tee;
pub mod traits;
pub mod vmm;
pub mod volume;
pub mod workload;

// Re-export commonly used types
pub use audit::{AuditAction, AuditConfig, AuditEvent, AuditOutcome};
pub use compose::ComposeConfig;
pub use config::{BoxConfig, ResourceConfig, ResourceLimits};
pub use error::{BoxError, Result};
pub use event::{BoxEvent, EventEmitter};
pub use exec::{ExecChunk, ExecEvent, ExecExit, ExecMetrics, StreamType};
pub use exec::{ExecOutput, ExecRequest};
pub use exec::{FileOp, FileRequest, FileResponse};
pub use exec::{EXEC_VSOCK_PORT, PORT_FWD_VSOCK_PORT};
pub use network::{IsolationMode, NetworkConfig, NetworkEndpoint, NetworkMode, NetworkPolicy};
pub use operator::{BoxAutoscaler, BoxAutoscalerSpec, BoxAutoscalerStatus, MetricType};
pub use platform::{
    BridgeNetworkBackend, HostGuestChannel, Platform, PlatformCapabilities, VmBackend,
};
pub use port::{normalize_port_maps, parse_port_mapping, PortMapping, PortProtocol};
pub use pty::PTY_VSOCK_PORT;
pub use scale::{
    InstanceDeregistration, InstanceEvent, InstanceHealth, InstanceInfo, InstanceRegistration,
    InstanceState, ScaleConfig, ScaleRequest, ScaleResponse,
};
pub use security::{SeccompMode, SecurityConfig};
pub use snapshot::{SnapshotConfig, SnapshotMetadata};
pub use tee::ATTEST_VSOCK_PORT;
pub use tee::{detect_tee, is_tee_available, TeeCapability, TeeType};
pub use traits::{
    AuditSink, CacheBackend, CacheEntry, CacheStats, CredentialProvider, EventBus, ImageRegistry,
    ImageStoreBackend, MetricsCollector, NetworkStoreBackend, NoopMetrics, PulledImage,
    SnapshotStoreBackend, StoredImage, VolumeStoreBackend,
};
pub use vmm::{
    Entrypoint, FsMount, InstanceSpec, NetworkInstanceConfig, TeeInstanceConfig, VmHandler,
    VmMetrics, VmmProvider, DEFAULT_SHUTDOWN_TIMEOUT_MS,
};
pub use volume::VolumeConfig;
pub use workload::{
    BoxRuntimeSpec, BoxWorkloadEnvelope, ExecutionLaunchMode, RuntimeClass, WorkloadKind,
};

/// A3S Box version
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

/// Get the A3S home directory.
///
/// Resolution order:
/// 1. `A3S_HOME` environment variable (if set)
/// 2. `~/.a3s` (via `dirs::home_dir()`)
/// 3. Fallback to `.a3s` in the current directory
pub fn dirs_home() -> std::path::PathBuf {
    if let Ok(home) = std::env::var("A3S_HOME") {
        return std::path::PathBuf::from(home);
    }
    dirs::home_dir()
        .map(|h| h.join(".a3s"))
        .unwrap_or_else(|| std::path::PathBuf::from(".a3s"))
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::Mutex;

    static ENV_LOCK: Mutex<()> = Mutex::new(());

    #[test]
    fn dirs_home_prefers_a3s_home_environment_variable() {
        let _guard = ENV_LOCK.lock().unwrap();
        let previous = std::env::var_os("A3S_HOME");
        let tmp = tempfile::tempdir().unwrap();

        std::env::set_var("A3S_HOME", tmp.path());
        assert_eq!(dirs_home(), tmp.path());

        match previous {
            Some(value) => std::env::set_var("A3S_HOME", value),
            None => std::env::remove_var("A3S_HOME"),
        }
    }

    #[test]
    fn dirs_home_defaults_to_dot_a3s_under_user_home_when_env_absent() {
        let _guard = ENV_LOCK.lock().unwrap();
        let previous = std::env::var_os("A3S_HOME");

        std::env::remove_var("A3S_HOME");
        let home = dirs_home();

        assert!(home.ends_with(".a3s"));
        if let Some(user_home) = dirs::home_dir() {
            assert_eq!(home, user_home.join(".a3s"));
        }

        match previous {
            Some(value) => std::env::set_var("A3S_HOME", value),
            None => std::env::remove_var("A3S_HOME"),
        }
    }
}
