// Sandbox Execution - Two-tier hybrid approach
// Tier 1: WASM (fast, <5ms) for WASI-compatible tasks
// Tier 2: Docker (warm pool, 80-150ms) for complex tasks

pub mod dispatcher;
pub mod docker_pool;
pub mod wasm_runtime;

// Re-export key types
pub use dispatcher::{SandboxDispatcher, SandboxTier};
pub use docker_pool::{DockerPool, DockerPoolConfig};
pub use wasm_runtime::{WasmRuntime, WasmRuntimeConfig};

/// Sandbox execution result
#[derive(Debug, Clone, PartialEq)]
pub struct SandboxResult {
    /// Command output (stdout)
    pub output: String,
    /// Error output (stderr)
    pub stderr: String,
    /// Exit code
    pub exit_code: i32,
    /// Execution duration in milliseconds
    pub duration_ms: u64,
    /// Tier used for execution
    pub tier: SandboxTier,
}

impl SandboxResult {
    /// Check if execution was successful (exit_code == 0)
    pub fn is_success(&self) -> bool {
        self.exit_code == 0
    }
}

/// Sandbox command to execute
#[derive(Debug, Clone)]
pub struct SandboxCommand {
    /// Command name (e.g., "peek", "grep", "slice")
    pub command: String,
    /// Command arguments
    pub args: Vec<String>,
    /// Optional stdin input
    pub stdin: Option<String>,
    /// Working directory (relative to sandbox root)
    pub workdir: Option<String>,
}

impl SandboxCommand {
    /// Create a new sandbox command
    pub fn new(command: impl Into<String>) -> Self {
        Self {
            command: command.into(),
            args: Vec::new(),
            stdin: None,
            workdir: None,
        }
    }

    /// Add an argument
    pub fn arg(mut self, arg: impl Into<String>) -> Self {
        self.args.push(arg.into());
        self
    }

    /// Add multiple arguments
    pub fn args(mut self, args: impl IntoIterator<Item = impl Into<String>>) -> Self {
        self.args.extend(args.into_iter().map(|a| a.into()));
        self
    }

    /// Set stdin input
    pub fn stdin(mut self, input: impl Into<String>) -> Self {
        self.stdin = Some(input.into());
        self
    }

    /// Set working directory
    pub fn workdir(mut self, dir: impl Into<String>) -> Self {
        self.workdir = Some(dir.into());
        self
    }
}
