// Copyright 2025 Neuraville Inc.
// SPDX-License-Identifier: Apache-2.0

/// STM32 platform implementations
///
/// Currently supports:
/// - STM32F4 series (ARM Cortex-M4, up to 180 MHz, up to 256KB SRAM)
///
/// Future support:
/// - STM32H7 series (ARM Cortex-M7, up to 480 MHz, up to 1MB SRAM)
use crate::hal::*;

/// STM32F4 platform structure
#[cfg(feature = "stm32f4")]
pub struct Stm32F4Platform {
    // Timer for timing functions
    start_time_us: u64,
}

#[cfg(feature = "stm32f4")]
impl Stm32F4Platform {
    /// Initialize STM32F4 platform
    ///
    /// # Returns
    /// Initialized Stm32F4Platform
    ///
    /// # Example
    /// ```no_run
    /// let platform = Stm32F4Platform::init().expect("Failed to init");
    /// ```
    pub fn init() -> Result<Self, &'static str> {
        Ok(Self { start_time_us: 0 })
    }

    /// Get STM32F4 chip model
    pub fn chip_model(&self) -> &'static str {
        "STM32F4xx"
    }
}

#[cfg(feature = "stm32f4")]
impl TimeProvider for Stm32F4Platform {
    fn get_time_us(&self) -> u64 {
        // STM32F4 would use SysTick or TIM for microsecond timing
        // This is a placeholder - actual implementation needs timer setup
        // Typically: DWT cycle counter or TIM2/TIM5 (32-bit timers)
        self.start_time_us
    }

    fn delay_us(&self, us: u32) {
        // STM32F4: Use cortex_m::asm::delay or busy-wait on DWT
        // Assuming 168 MHz (STM32F407)
        let cycles = (us as u64 * 168) / 1000; // cycles = us * (MHz / 1000)
        for _ in 0..cycles {
            cortex_m::asm::nop();
        }
    }

    fn delay_ms(&self, ms: u32) {
        self.delay_us(ms * 1000);
    }
}

#[cfg(feature = "stm32f4")]
impl SerialIO for Stm32F4Platform {
    type Error = ();

    fn write(&mut self, data: &[u8]) -> Result<usize, Self::Error> {
        // STM32F4: Would use USART peripheral
        // This is a placeholder - actual implementation needs serial setup
        Ok(data.len())
    }

    fn read(&mut self, _buffer: &mut [u8]) -> Result<usize, Self::Error> {
        // Non-blocking read from USART
        Ok(0)
    }

    fn flush(&mut self) -> Result<(), Self::Error> {
        Ok(())
    }
}

#[cfg(feature = "stm32f4")]
impl Logger for Stm32F4Platform {
    fn log(&self, _level: LogLevel, _message: &str) {
        // STM32F4: Would write log message via ITM or USART
        // In a real implementation, this would:
        // 1. Format the message (using ufmt for no_std)
        // 2. Write to ITM (Instrumentation Trace Macrocell) for debug
        // 3. Or write to USART for production
        // For now, this is a no-op placeholder
    }
}

#[cfg(feature = "stm32f4")]
impl Platform for Stm32F4Platform {
    fn name(&self) -> &'static str {
        self.chip_model()
    }

    fn cpu_frequency_hz(&self) -> u32 {
        // STM32F407 runs at 168 MHz (with PLL)
        // STM32F429 can run at 180 MHz
        168_000_000
    }

    fn available_memory_bytes(&self) -> usize {
        // STM32F407 has 192KB SRAM (128KB + 64KB CCM)
        // STM32F429 has 256KB SRAM
        192_000
    }
}

// Placeholder for when stm32f4 feature is not enabled
#[cfg(not(feature = "stm32f4"))]
pub struct Stm32F4Platform;

#[cfg(not(feature = "stm32f4"))]
impl Stm32F4Platform {
    pub fn init() -> Result<Self, &'static str> {
        Err("STM32F4 feature not enabled. Rebuild with --features stm32f4")
    }
}
