#![allow(missing_docs)]
#![no_std]
#![no_main]

use core::convert::Infallible;

use embassy_executor::Spawner;
use embassy_time::Duration;
use esp_backtrace as _;
use log::info;

use device_envoy_esp::{
    init_and_start, led_strip,
    led_strip::{colors, Current, Frame1d, Gamma, LedStrip},
    Result,
};

esp_bootloader_esp_idf::esp_app_desc!();

led_strip! {
    LedStripLen96 {
        pin: GPIO18,
        len: 96,
        max_current: Current::Milliamps(1000),
        gamma: Gamma::Linear,
        max_frames: 3,
    }
}

fn animate_rgb_cycle<const N: usize>(led_strip: &impl LedStrip<N>) {
    // Create a sequence of frames and durations and then animate them (looping, until replaced).
    let frame_duration = Duration::from_millis(300);
    led_strip.animate([
        (Frame1d::filled(colors::RED), frame_duration),
        (Frame1d::filled(colors::GREEN), frame_duration),
        (Frame1d::filled(colors::BLUE), frame_duration),
    ]);
}

#[esp_rtos::main]
async fn main(spawner: Spawner) -> ! {
    match inner_main(spawner).await {
        Ok(infallible) => match infallible {},
        Err(error) => panic!("{error:?}"),
    }
}

async fn inner_main(spawner: Spawner) -> Result<Infallible> {
    init_and_start!(p, rmt80: rmt80, mode: rmt_mode::Blocking);
    esp_println::logger::init_logger(log::LevelFilter::Info);

    info!("LED strip trait example 2: RGB animation on GPIO18");

    let led_strip_len96 = LedStripLen96::new(p.GPIO18, rmt80.channel0, spawner)?;
    animate_rgb_cycle(led_strip_len96);

    core::future::pending().await
}
