// src/bin/main.rs
#![no_std]
#![no_main]

use defmt::*;
use {defmt_rtt as _, panic_probe as _};

use embassy_executor::Spawner;
use embassy_stm32::usart::{BufferedInterruptHandler, BufferedUart, Config};
use embassy_stm32::bind_interrupts;
use embassy_stm32::peripherals;
use embassy_time::Instant;
use static_cell::StaticCell;

use async_uart::uart::usart1;

bind_interrupts!(struct Irqs {
    USART1 => BufferedInterruptHandler<peripherals::USART1>;
});

#[embassy_executor::main]
async fn main(spawner: Spawner) {
    info!("boot");
    let p = embassy_stm32::init(Default::default());

    let mut cfg = Config::default();
    cfg.baudrate = 230_400;

    static TX_BUF: StaticCell<[u8; 256]> = StaticCell::new();
    static RX_BUF: StaticCell<[u8; 256]> = StaticCell::new();

    let uart = 
        BufferedUart::new(
            p.USART1,
            p.PA10,
            p.PA9,
            TX_BUF.init([0; 256]),
            RX_BUF.init([0; 256]),
            Irqs,
            cfg,
        ).unwrap();
    let handle = usart1::setup_and_spawn(&spawner, uart, cfg.baudrate);

    let mut rx_buf = [0u8; 64];
    let mut last_yield = Instant::now();

    loop {
        if let Ok(n) = handle.rx.try_read(&mut rx_buf) {
            if n > 0 {
                if let Ok(s) = core::str::from_utf8(&rx_buf[..n]) {
                    info!("RX got: {}", s);
                } else {
                    info!("RX got (non‑utf8): {:?}", &rx_buf[..n]);
                }
            }
        }

        if Instant::now().duration_since(last_yield) >= handle.yield_period {
            embassy_futures::yield_now().await;
            last_yield = Instant::now();
        }
    }
}
