//! Driver code generation templates

use crate::utils::to_pascal_case;

/// Generate sensor driver template
pub fn sensor_driver(name: &str) -> String {
    format!(
        r#"//! {} - Sensor Driver
//!
//! Auto-generated driver template.

use anyhow::Result;
use mecha10_core::Driver;
use serde::{{Deserialize, Serialize}};
use tracing::info;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {}Config {{
    pub update_rate_hz: f64,
}}

pub struct {} {{
    config: {}Config,
}}

impl {} {{
    pub fn new(config: {}Config) -> Self {{
        Self {{ config }}
    }}
}}

#[async_trait::async_trait]
impl Driver for {} {{
    async fn initialize(&mut self) -> Result<()> {{
        info!("Initializing {} driver");
        // TODO: Initialize hardware/sensor
        Ok(())
    }}

    async fn update(&mut self) -> Result<()> {{
        // TODO: Read sensor data
        // TODO: Publish to message bus
        Ok(())
    }}

    async fn shutdown(&mut self) -> Result<()> {{
        info!("Shutting down {} driver");
        Ok(())
    }}
}}
"#,
        name,
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        name,
        name
    )
}

/// Generate actuator driver template
pub fn actuator_driver(name: &str) -> String {
    format!(
        r#"//! {} - Actuator Driver
//!
//! Auto-generated driver template.

use anyhow::Result;
use mecha10_core::Driver;
use serde::{{Deserialize, Serialize}};
use tracing::info;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {}Config {{
    pub max_speed: f64,
    pub acceleration: f64,
}}

pub struct {} {{
    config: {}Config,
}}

impl {} {{
    pub fn new(config: {}Config) -> Self {{
        Self {{ config }}
    }}

    pub async fn set_command(&mut self, command: f64) -> Result<()> {{
        // TODO: Send command to actuator
        Ok(())
    }}
}}

#[async_trait::async_trait]
impl Driver for {} {{
    async fn initialize(&mut self) -> Result<()> {{
        info!("Initializing {} driver");
        // TODO: Initialize actuator
        Ok(())
    }}

    async fn update(&mut self) -> Result<()> {{
        // TODO: Process actuator commands from message bus
        Ok(())
    }}

    async fn shutdown(&mut self) -> Result<()> {{
        info!("Shutting down {} driver");
        // TODO: Stop actuator safely
        Ok(())
    }}
}}
"#,
        name,
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        name,
        name
    )
}

/// Generate controller driver template
pub fn controller_driver(name: &str) -> String {
    format!(
        r#"//! {} - Controller Driver
//!
//! Auto-generated driver template.

use anyhow::Result;
use mecha10_core::Driver;
use serde::{{Deserialize, Serialize}};
use tracing::info;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct {}Config {{
    pub control_rate_hz: f64,
}}

pub struct {} {{
    config: {}Config,
}}

impl {} {{
    pub fn new(config: {}Config) -> Self {{
        Self {{ config }}
    }}
}}

#[async_trait::async_trait]
impl Driver for {} {{
    async fn initialize(&mut self) -> Result<()> {{
        info!("Initializing {} controller");
        // TODO: Initialize controller
        Ok(())
    }}

    async fn update(&mut self) -> Result<()> {{
        // TODO: Run control loop
        Ok(())
    }}

    async fn shutdown(&mut self) -> Result<()> {{
        info!("Shutting down {} controller");
        Ok(())
    }}
}}
"#,
        name,
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        to_pascal_case(name),
        name,
        name
    )
}
