// 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::path::{Path, PathBuf};
use structopt::StructOpt;
use thiserror::Error;

use crate::app::config::process_config_file;
use crate::app::{TransportWrapper, TransportWrapperBuilder};
use crate::transport::hyperdebug::c2d2::C2d2Flavor;
use crate::transport::hyperdebug::{CW310Flavor, StandardFlavor};
use crate::transport::{EmptyTransport, Transport};
use crate::util::parse_int::ParseInt;

mod cw310;
mod hyperdebug;
mod nexus;
mod proxy;
mod ti50emulator;
mod ultradebug;
mod verilator;

#[derive(Debug, StructOpt)]
pub struct BackendOpts {
    #[structopt(long, default_value = "", help = "Name of the debug interface")]
    pub interface: String,

    #[structopt(long, parse(try_from_str = u16::from_str),
                help="USB Vendor ID of the interface")]
    pub usb_vid: Option<u16>,
    #[structopt(long, parse(try_from_str = u16::from_str),
                help="USB Product ID of the interface")]
    pub usb_pid: Option<u16>,
    #[structopt(long, help = "USB serial number of the interface")]
    pub usb_serial: Option<String>,

    #[structopt(flatten)]
    pub cw310_opts: cw310::Cw310Opts,

    #[structopt(flatten)]
    pub verilator_opts: verilator::VerilatorOpts,

    #[structopt(flatten)]
    pub proxy_opts: proxy::ProxyOpts,

    #[structopt(flatten)]
    pub ti50emulator_opts: ti50emulator::Ti50EmulatorOpts,

    #[structopt(long, number_of_values(1), help = "Configuration files")]
    pub conf: Vec<PathBuf>,
}

#[derive(Error, Debug)]
pub enum Error {
    #[error("Unknown interface {0}")]
    UnknownInterface(String),
}

/// Creates the requested backend interface according to [`BackendOpts`].
pub fn create(args: &BackendOpts) -> Result<TransportWrapper> {
    let interface = args.interface.as_str();
    let (backend, default_conf) = match interface {
        "" => (create_empty_transport()?, None),
        "proxy" => (proxy::create(&args.proxy_opts)?, None),
        "verilator" => (
            verilator::create(&args.verilator_opts)?,
            Some(Path::new("/__builtin__/opentitan_verilator.json")),
        ),
        "ti50emulator" => (
            ti50emulator::create(&args.ti50emulator_opts)?,
            Some(Path::new("/__builtin__/ti50emulator.json")),
        ),
        "ultradebug" => (
            ultradebug::create(args)?,
            Some(Path::new("/__builtin__/opentitan_ultradebug.json")),
        ),
        "hyper310" => (
            hyperdebug::create::<CW310Flavor>(args)?,
            Some(Path::new("/__builtin__/hyperdebug_cw310.json")),
        ),
        "hyperdebug" => (hyperdebug::create::<StandardFlavor>(args)?, None),
        "hyperdebug_dfu" => (hyperdebug::create_dfu(args)?, None),
        "c2d2" => (
            hyperdebug::create::<C2d2Flavor>(args)?,
            Some(Path::new("/__builtin__/h1dx_devboard.json")),
        ),
        "cw310" => (
            cw310::create(args)?,
            Some(Path::new("/__builtin__/opentitan_cw310.json")),
        ),
        "nexus" => (
            nexus::create(args)?,
            Some(Path::new("/__builtin__/nexus.json")),
        ),
        _ => return Err(Error::UnknownInterface(interface.to_string()).into()),
    };
    let mut env = TransportWrapperBuilder::new(backend);

    if args.conf.is_empty() {
        if let Some(conf_file) = default_conf {
            process_config_file(&mut env, conf_file)?
        }
    }
    for conf_file in &args.conf {
        process_config_file(&mut env, conf_file.as_ref())?
    }
    env.build()
}

pub fn create_empty_transport() -> Result<Box<dyn Transport>> {
    Ok(Box::new(EmptyTransport))
}
