//! Ghost CLI library.

use clap::Parser;
use ghost_client_cli::commands::{KeySubcommand, VanityCmd};

#[derive(Debug, clap::Subcommand)]
pub enum KeyCmd {
    /// Key utility for the CLI
    #[clap(flatten)]
    KeyCli(KeySubcommand),

    /// Sign a message, with a given (secret) key.
    Sign(sc_cli::SignCmd),

    /// Generate a seed that provides a vanity address/
    Vanity(VanityCmd),

    /// Verify a signature for a mesage, provided on STDIN, with a given
    /// (public or secret) key.
    Verify(sc_cli::VerifyCmd),
}

impl KeyCmd {
    pub fn run<C: sc_cli::SubstrateCli>(&self, cli: &C) -> Result<(), sc_cli::Error> {
        match self {
            KeyCmd::KeyCli(cmd) => cmd.run(cli),
            KeyCmd::Sign(cmd) => cmd.run(),
            KeyCmd::Vanity(cmd) => cmd.run(),
            KeyCmd::Verify(cmd) => cmd.run(),
        }
    }
}

/// Possible subcommands of the main binary.
#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
    /// Build a chain specification.
    BuildSpec(sc_cli::BuildSpecCmd),

    /// Validate blocks.
    CheckBlock(sc_cli::CheckBlockCmd),

    /// Export blocks.
    ExportBlocks(sc_cli::ExportBlocksCmd),

    /// Export the state of a given block into a chain spec.
    ExportState(sc_cli::ExportStateCmd),

    /// Import blocks.
    ImportBlocks(sc_cli::ImportBlocksCmd),

    /// Remove the whole chain.
    PurgeChain(sc_cli::PurgeChainCmd),

    /// Revert the chain to a previous state.
    Revert(sc_cli::RevertCmd),

    /// The custom benchmark subcommmand benchmarking runtime pallets.
    #[clap(subcommand)]
    Benchmark(frame_benchmarking_cli::BenchmarkCmd),

    /// Key managment cli utilities.
    #[clap(subcommand)]
    Key(KeyCmd),

    /// Db meta columns information
    ChainInfo(sc_cli::ChainInfoCmd),
}

#[allow(missing_docs)]
#[derive(Debug, Parser)]
#[group(skip)]
pub struct RunCmd {
    #[clap(flatten)]
    pub base: sc_cli::RunCmd,

    /// Disable autimatic hardware benchmarks.
    ///
    /// By default these benchamrks are automatically ran at startup and
    /// measure the CPU speed, the memory bandwidth and the disk speed.
    ///
    /// The results, are then printed out in the logs, and also send as part
    /// of telemetry, if telemetry is enabled.
    #[arg(long)]
    pub no_hardware_benchmarks: bool,

    /// Enable the block authoring backoff that is triggered when finality is
    /// lagging.
    #[arg(long)]
    pub force_authoring_backoff: bool,

    /// Add the destination address to the `pyroscope` agent.
    /// Must be valid socket address, of format `IP:PORT` (commonly `127.0.0.1:4040`).
    #[arg(long)]
    pub pyroscope_server: Option<String>,
}

/// An overarching CLI command definition
#[derive(Debug, clap::Parser)]
pub struct Cli {
    /// Possible subcommands with parameters.
    #[clap(subcommand)]
    pub subcommand: Option<Subcommand>,

    /// Base command line.
    #[clap(flatten)]
    pub run: RunCmd,

    /// Parameters used to create the storage monitor.
    #[clap(flatten)]
    pub storage_monitor: sc_storage_monitor::StorageMonitorParams,
}
