// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use std::time::Duration;
use structopt::clap::arg_enum;
use thiserror::Error;

use crate::io::gpio::GpioPin;
use crate::io::spi::Target;

mod primitive;
mod legacy;

#[derive(Debug, Error)]
pub enum BootstrapError {
    #[error("Invalid hash length: {0}")]
    InvalidHashLength(usize),
}

arg_enum! {
    /// `BootstrapProtocol` describes the supported types of bootstrap.
    /// The `Primitive` protocol is used by OpenTitan during development.
    /// The `Legacy` protocol is used by previous generations of Google Titan-class chips.
    /// The `Eeprom` protocol is planned to be implemented for OpenTitan.
    /// The 'Emulator' value indicates that this tool has a direct way
    /// of communicating with the OpenTitan emulator, to replace the
    /// contents of the emulated flash storage.
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    pub enum BootstrapProtocol {
        Primitive,
        Legacy,
        Eeprom,
        Emulator,
    }
}

// Implementations of bootstrap need to implement the `UpdateProtocol` trait.
trait UpdateProtocol {
    fn update(&self, spi: &dyn Target, payload: &[u8]) -> Result<()>;
}

/// Options which control bootstrap behavior.
/// The meaning of each of these values depends on the specific bootstrap protocol being used.
#[derive(Debug, Default)]
pub struct BootstrapOptions {
    /// How long to hold the reset pin during the reset sequence.
    pub reset_delay: Option<Duration>,
    /// How long to delay between sending bootstrap frames.
    pub inter_frame_delay: Option<Duration>,
    /// How long to delay during a flash erase operation.
    pub flash_erase_delay: Option<Duration>,
}

/// Bootstrap wraps and drives the various bootstrap protocols.
pub struct Bootstrap {
    pub protocol: BootstrapProtocol,
    reset_delay: Duration,
    updater: Box<dyn UpdateProtocol>,
}

impl Bootstrap {
    const RESET_DELAY: Duration = Duration::from_millis(200);

    /// Consrtuct a `Bootstrap` struct configured to use `protocol` and `options`.
    pub fn new(protocol: BootstrapProtocol, options: BootstrapOptions) -> Result<Self> {
        let updater: Box<dyn UpdateProtocol> = match protocol {
            BootstrapProtocol::Primitive => Box::new(primitive::Primitive::new(&options)),
            BootstrapProtocol::Legacy => Box::new(legacy::Legacy::new(&options)),
            BootstrapProtocol::Eeprom => {
                unimplemented!();
            }
            BootstrapProtocol::Emulator => {
                // Not intended to be implemented by this struct.
                unimplemented!();
            }
        };
        Ok(Bootstrap {
            protocol,
            reset_delay: options.reset_delay.unwrap_or(Self::RESET_DELAY),
            updater: updater,
        })
    }

    /// Perform the update, sending the firmware `payload` to the `spi` target,
    /// using `gpio` to sequence the reset and bootstrap pins.
    pub fn update(
        &self,
        spi: &dyn Target,
        reset: &dyn GpioPin,
        bootstrap: &dyn GpioPin,
        payload: &[u8],
    ) -> Result<()> {
        log::info!("Asserting bootstrap pins...");
        bootstrap.write(true)?;

        log::info!("Restting the target...");
        reset.write(false)?; // Low active
        std::thread::sleep(self.reset_delay);
        reset.write(true)?; // Release reset
        std::thread::sleep(self.reset_delay);

        log::info!("Performing bootstrap...");
        self.updater.update(spi, payload)?;

        log::info!("Releasing bootstrap pins...");
        bootstrap.write(false)?;
        Ok(())
    }
}
