/*! Handling CLI commands */
/*
    Copyright (C) 2022 John Goerzen <jgoerzen@complete.org>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

use crate::cmd::cmd_exec::{ProcessOpts, QueueProcessOpts};
use crate::cmd::cmd_prepare::{PrepareOpts, SFOpts, SFSetOpts};
use crate::cmd::cmd_queue::{
    QueueInitOpts, QueueJobOpts, QueueOpts, QueueOptsWithDecoder, QueueSetSeqOpts,
};
use clap::{Args, Parser, Subcommand};
use tracing::*;
use uuid::Uuid;
pub mod cmd_exec;
pub mod cmd_info;
pub mod cmd_prepare;
pub mod cmd_queue;

/// Sub-commands
#[derive(Debug, Subcommand)]
pub enum Command {
    /// Display a UUID to stdout
    GenUUID,

    /// Display a fspl-*.fspl filename to stdout
    GenFilename,

    /// Prepare a command for transmission, writing to stdout
    Prepare(PrepareOpts),

    /// Prepare a NOP packet for transmission, writing to stdout
    PrepareNOP(SFOpts),

    /// Prepare a fail packet for transmission, writing to stdout
    PrepareFail(SFOpts),

    /// Get the next sequence number for prepare
    PrepareGetNext(SFOpts),

    /// Set the next sequence number for prepare
    PrepareSetNext(SFSetOpts),

    /// Process a queue
    QueueProcess(QueueProcessOpts),

    /// Initialize a queue
    QueueInit(QueueInitOpts),

    /// Show information about a specific job ID in a queue
    QueueInfo(QueueJobOpts),

    /// Save a packet from stdin to a queue
    QueueWrite(QueueOpts),

    /// Gets information about the jobs in a queue
    QueueLs(QueueOptsWithDecoder),

    /// Prints the next sequence number for the queue
    QueueGetNext(QueueOpts),

    /// Sets the next sequence number for the queue
    QueueSetNext(QueueSetSeqOpts),

    /// Dump the payload of a job to stdout
    QueuePayload(QueueJobOpts),

    /// Get information about a packet piped to filespooler on stdin
    StdinInfo,

    /// Dumps the payload from the packet on stdin to stdout
    StdinPayload,

    /// Process a command from a job packet read from stdin
    StdinProcess(ProcessOpts),

    /// Show the license information
    ShowLicense,
}

#[derive(Debug, Args)]
pub struct GlobalOpts {
    /// Gives the logging (to stderr) level.  Default is INFO.  Options
    /// in order from most to least info: TRACE, DEBUG, INFO, WARN, ERROR.
    #[arg(long, short, value_name = "LEVEL", default_value_t = Level::INFO)]
    pub log_level: Level,
}

#[derive(Parser, Debug)]
#[command(author, version, about)]
pub struct Cli {
    #[clap(flatten)]
    pub globalopts: GlobalOpts,

    #[clap(subcommand)]
    pub command: Command,
}

pub fn parse() -> Cli {
    Cli::parse()
}

pub static LICENSE: &str = "\
Filespooler

    Copyright (C) 2022 John Goerzen <jgoerzen@complete.org>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
";

pub fn cmd_showlicense() -> Result<(), anyhow::Error> {
    println!("{}", LICENSE);

    Ok(())
}

pub fn cmd_genuuid() -> Result<(), anyhow::Error> {
    let mut buf = Uuid::encode_buffer();
    let uuid = Uuid::new_v4().hyphenated().encode_lower(&mut buf);
    println!("{}", uuid);
    Ok(())
}

pub fn cmd_genfilename() -> Result<(), anyhow::Error> {
    let mut buf = Uuid::encode_buffer();
    let uuid = Uuid::new_v4().hyphenated().encode_lower(&mut buf);
    println!("fspl-{}.fspl", uuid);
    Ok(())
}
