use clap::builder::PossibleValue;
use clap::Parser;
use logappend::logappend::InputStreamType;

#[derive(Debug, Clone)]
enum PipeMode {
    Passthrough,
    Logsplit,
}

impl clap::ValueEnum for PipeMode {
    fn value_variants<'a>() -> &'a [Self] {
        &[Self::Passthrough, Self::Logsplit]
    }

    fn to_possible_value(&self) -> Option<PossibleValue> {
        match self {
            PipeMode::Passthrough => Some(PossibleValue::new("forward")),
            PipeMode::Logsplit => Some(PossibleValue::new("logsplit")),
        }
    }
}

impl From<PipeMode> for InputStreamType {
    fn from(value: PipeMode) -> Self {
        match value {
            PipeMode::Passthrough => InputStreamType::FeedThrough,
            PipeMode::Logsplit => InputStreamType::LogSplit,
        }
    }
}

#[derive(Debug, Parser)]
#[command(author, version, about, long_about = None)]
struct Opts {
    #[arg(long, default_value = ".")]
    dir: String,
    #[arg(long, default_value = "30")]
    total_mb: usize,
    #[arg(long, default_value = "3")]
    file_mb: usize,
    #[arg(long, value_enum, default_value_t = PipeMode::Passthrough)]
    stdout_mode: PipeMode,
    #[arg(long, value_enum, default_value_t = PipeMode::Passthrough)]
    stderr_mode: PipeMode,
    exe: String,
    args: Vec<String>,
}

impl Opts {
    fn total_max(&self) -> usize {
        1024 * 1024 * self.total_mb
    }

    fn file_max(&self) -> usize {
        1024 * 1024 * self.file_mb
    }
}

fn main() {
    let opts = Opts::parse();
    match logappend::logappend::logappend_wrap(
        &opts.dir,
        opts.total_max(),
        opts.file_max(),
        opts.exe,
        opts.args,
        opts.stdout_mode.into(),
        opts.stderr_mode.into(),
    ) {
        Ok(ec) => {
            let ec = ec.code().unwrap_or(0);
            std::process::exit(ec);
        }
        Err(_e) => {
            std::process::exit(libc::EXIT_FAILURE);
        }
    }
}
