use std::{fs, path::PathBuf};

use clap::Parser;

use crate::config::{IoMapping, MemoryMap};

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct DsaArgs {
    /// Memory map to use on boot.
    /// Overrides default value.
    #[arg(long = "mmap")]
    memory_map: Option<PathBuf>,

    #[arg(long = "bin")]
    binary: Option<PathBuf>,

    #[arg(long = "iomap")]
    io_map: Option<PathBuf>,
}

impl DsaArgs {
    pub fn get_memory_map(&self) -> MemoryMap {
        self.memory_map
            .as_ref()
            .and_then(|m| {
                fs::read_to_string(m)
                    .ok()
                    .and_then(|map| ron::from_str(&map).ok())
            })
            .unwrap_or_else(|| {
                ron::from_str(include_str!("./config/default/dsa.mmap.ron")).unwrap()
            })
    }

    pub fn get_binary(&self) -> Option<Vec<u8>> {
        self.binary
            .clone()
            .and_then(|path| Some(fs::read(path).unwrap()))
    }

    pub fn get_io_map(&self) -> Vec<IoMapping> {
        self.io_map
            .as_ref()
            .and_then(|m| {
                fs::read_to_string(m)
                    .ok()
                    .and_then(|map| ron::from_str(&map).ok())
            })
            .unwrap_or_else(|| {
                ron::from_str(include_str!("./config/default/dsa.iomap.ron")).unwrap()
            })
    }
}
