//! Example usage of the #[derive(Config)] macro
//!
//! This example demonstrates how to use the Config derive macro to automatically
//! generate configuration loading methods.

use mecha10::prelude::*;

/// Camera configuration with automatic loading
#[derive(Debug, Clone, Serialize, Deserialize, Config)]
#[config(path = "config/camera.yaml", env_prefix = "CAMERA", env_var = "CAMERA_CONFIG")]
pub struct CameraConfig {
    /// Frames per second
    pub fps: f32,

    /// Image width
    pub width: u32,

    /// Image height
    pub height: u32,

    /// Camera device path (optional)
    pub device: Option<String>,

    /// Enable auto-exposure
    #[serde(default)]
    pub auto_exposure: bool,
}

/// Simple configuration with default settings
#[derive(Debug, Clone, Serialize, Deserialize, Config)]
pub struct RobotConfig {
    pub max_speed: f32,
    pub wheel_radius: f32,
}

fn main() -> Result<()> {
    // Example 1: Load from default path or environment variable
    // Tries:
    //   1. CAMERA_CONFIG env var for file path
    //   2. config/camera.yaml
    let camera_config = CameraConfig::load()?;
    println!("Camera config: {:?}", camera_config);

    // Example 2: Load from specific file
    let camera_config = CameraConfig::load_from_file("custom_camera.yaml")?;
    println!("Custom camera config: {:?}", camera_config);

    // Example 3: Load from environment variables
    // Looks for: CAMERA_FPS, CAMERA_WIDTH, CAMERA_HEIGHT, CAMERA_DEVICE, CAMERA_AUTO_EXPOSURE
    let camera_config = CameraConfig::load_from_env()?;
    println!("Camera config from env: {:?}", camera_config);

    // Example 4: Load with fallback chain
    // Tries:
    //   1. CAMERA_CONFIG env var
    //   2. config/camera.yaml
    //   3. CAMERA_* environment variables
    //   4. Default configuration (if provided)
    let default = CameraConfig {
        fps: 30.0,
        width: 640,
        height: 480,
        device: None,
        auto_exposure: true,
    };
    let camera_config = CameraConfig::load_with_fallback(Some(default))?;
    println!("Camera config with fallback: {:?}", camera_config);

    // Example 5: Inspect configuration metadata
    println!("Default config path: {}", CameraConfig::default_config_path());
    println!("Config env var: {}", CameraConfig::config_env_var());
    println!("Env prefix: {}", CameraConfig::env_prefix());

    // Example 6: Robot config with minimal attributes (uses defaults)
    // Default path: config/robotconfig.yaml
    // Default env var: ROBOTCONFIG_CONFIG
    // Default env prefix: ROBOTCONFIG
    let robot_config = RobotConfig::load()?;
    println!("Robot config: {:?}", robot_config);

    Ok(())
}

// Example config files:

// config/camera.yaml:
// ```yaml
// fps: 60.0
// width: 1920
// height: 1080
// device: "/dev/video0"
// auto_exposure: false
// ```

// Environment variables:
// ```bash
// export CAMERA_CONFIG="custom_camera.yaml"
// export CAMERA_FPS=30
// export CAMERA_WIDTH=640
// export CAMERA_HEIGHT=480
// export CAMERA_DEVICE="/dev/video1"
// export CAMERA_AUTO_EXPOSURE=true
// ```
