// Licensed under the Apache-2.0 license

//! I2C Slave Echo Application
//!
//! Sits on I2C2 at address 0x42 and implements a simple register model:
//!
//! - **Write** `[reg, value]` — stores `value` at `reg` and prints the access.
//! - **Write** `[reg]` followed by **Read** — returns the stored value for `reg`
//!   and prints the access.
//!
//! # Protocol
//!
//! ```text
//! Master writes [reg, val]  →  slave stores reg_map[reg] = val
//!                              prints: "WRITE reg=0xRR val=0xVV"
//!
//! Master writes [reg]       →  slave sets read pointer to reg
//! Master reads N bytes      →  slave returns reg_map[reg..reg+N]
//!                              prints: "READ  reg=0xRR val=0xVV"
//! ```
//!
//! # Hardware
//!
//! The AST1060 I2C2 controller is used in simultaneous master+slave mode:
//! master operations use the I2CM* register set, slave operations use I2CS*.

#![no_main]
#![no_std]

use app_i2c_slave_echo::handle;
use i2c_api::{BusIndex, I2cAddress, I2cTargetClient, SlaveEventKind};
use i2c_client::IpcI2cClient;
use pw_status::Result;
use userspace::entry;

/// I2C bus index (I2C2).
const SLAVE_BUS: BusIndex = BusIndex::BUS_2;

/// Slave address.
const SLAVE_ADDR: u8 = 0x42;

/// Number of registers in the echo register map.
const REG_MAP_SIZE: usize = 256;

fn slave_echo_loop() -> Result<()> {
    let mut client = IpcI2cClient::new(handle::I2C);

    let addr = I2cAddress::new(SLAVE_ADDR).map_err(|_| pw_status::Error::InvalidArgument)?;

    // Configure and enable slave mode.
    client
        .configure_target_address(SLAVE_BUS, addr)
        .map_err(|_| pw_status::Error::Internal)?;
    client
        .enable_receive(SLAVE_BUS)
        .map_err(|_| pw_status::Error::Internal)?;

    pw_log::info!(
        "I2C slave echo running on bus {} at address 0x{:02x}",
        SLAVE_BUS.value() as u32,
        SLAVE_ADDR as u32,
    );

    // Register map — all bytes initialised to zero.
    let mut reg_map = [0u8; REG_MAP_SIZE];
    // Current register pointer (set by a 1-byte write, used for reads).
    let mut reg_ptr: u8 = 0;

    // Pre-load the initial read response.
    let _ = client.slave_set_response(SLAVE_BUS, &[reg_map[reg_ptr as usize]]);

    let mut rx_buf = [0u8; 32];

    loop {
        match client.slave_wait_event(SLAVE_BUS, &mut rx_buf) {
            Ok((SlaveEventKind::DataReceived, n)) => {
                match n {
                    0 => {
                        // Zero-length write — ignore (e.g. probe).
                    }
                    1 => {
                        // Register pointer set; update read response.
                        reg_ptr = rx_buf[0];
                        let val = reg_map[reg_ptr as usize];
                        // pw_log::info!(
                        //     "READ  reg=0x{:02x} val=0x{:02x}",
                        //     reg_ptr as u32,
                        //     val as u32,
                        // );
                        let _ = client.slave_set_response(SLAVE_BUS, &[val]);
                    }
                    _ => {
                        // Write: byte 0 = register address, byte 1 = value.
                        reg_ptr = rx_buf[0];
                        let val = rx_buf[1];
                        reg_map[reg_ptr as usize] = val;
                        // pw_log::info!(
                        //     "WRITE reg=0x{:02x} val=0x{:02x}",
                        //     reg_ptr as u32,
                        //     val as u32,
                        // );
                        // Update read response in case master reads back immediately.
                        let _ = client.slave_set_response(SLAVE_BUS, &[val]);
                    }
                }
            }
            Ok((SlaveEventKind::ReadRequest, _)) => {
                // Master read our pre-loaded response; log it.
                let val = reg_map[reg_ptr as usize];
                // pw_log::info!(
                //     "READ  reg=0x{:02x} val=0x{:02x}",
                //     reg_ptr as u32,
                //     val as u32,
                // );
                let _ = val;
            }
            Ok((SlaveEventKind::Stop, _)) => {
                // Stop condition — nothing to do.
            }
            Err(_) => {
                // Timeout or error — keep looping.
            }
        }
    }
}

#[entry]
fn entry() -> ! {
    pw_log::info!("I2C slave echo starting");
    let _ = slave_echo_loop();
    loop {}
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}
