pub mod actions;
pub mod ham;
use rave_engine::types::entries::{PieceDefinition, PieceDefinitionExt};
use structopt::StructOpt;
pub mod display;

#[derive(Debug, StructOpt, Clone)]
pub struct CommonOpts {
    #[structopt(long, env = "ADMIN_PORT", default_value = "8800")]
    pub admin_port: u16,

    #[structopt(long, env = "APP_PORT", default_value = "30000")]
    pub app_port: u16,

    #[structopt(long, env = "APP_ID", default_value = "domino-progenitor")]
    pub app_id: String,
}

#[derive(Debug, StructOpt)]
#[structopt(name = "domino_cli", about = "An interface for the Domino app.")]
pub struct Cli {
    #[structopt(flatten)]
    pub common: CommonOpts,

    #[structopt(subcommand)]
    pub cmd: Command,
}

#[derive(Debug, StructOpt)]
pub enum Command {
    #[structopt(
        name = "zome_call",
        alias = "z",
        about = "Call most zome functions provided by the Domino app. Use at your own risk"
    )]
    ZomeCommand(ZomeCommand),

    #[structopt(
        name = "progenitor",
        alias = "p",
        about = "Call a progenitor function, Note: If your not a progenitor most of these commands will fail for your agent "
    )]
    ProgenitorCommand(ProgenitorCommand),

    #[structopt(name = "dashboard", alias = "d", about = "Display your dashboard")]
    Dashboard,
}

#[derive(Debug, StructOpt)]
pub enum ProgenitorCommand {
    #[structopt(name = "dashboard", alias = "d", about = "Display your dashboard")]
    Dashboard,

    #[structopt(
        name = "init",
        alias = "i",
        about = "Initialize the system (only need to run once)"
    )]
    Init {
        #[structopt(long, about = "The path to the library of RAVE templates")]
        library_path: String,
    },

    #[structopt(
        name = "initialize_pool",
        alias = "ip",
        about = "Initialize or update the pool definition"
    )]
    InitializePoolDefinition,

    #[structopt(
        name = "get_current_pool_definition",
        alias = "gpd",
        about = "Get the current pool definitions"
    )]
    GetPoolDefinitions,

    #[structopt(
        name = "add_pool_pieces",
        alias = "ap",
        about = "Add a new pool piece to the pool"
    )]
    AddPoolPieces(PieceDefinition),

    #[structopt(
        name = "update_pool_pieces",
        alias = "up",
        about = "Update an existing pool piece"
    )]
    UpdatePoolPieces(PieceDefinitionExt),

    #[structopt(
        name = "get_pool_pieces_details",
        alias = "gpd",
        about = "Get pool pieces details"
    )]
    GetPoolPiecesDetails,

    #[structopt(
        name = "create_swim_lane_definition",
        alias = "csld",
        about = "Create a new swim lane definition"
    )]
    CreateSwimLaneDefinition {
        #[structopt(long)]
        definition: String, // JSON string containing SwimLaneDefinition
    },

    #[structopt(
        name = "update_swim_lane_definition",
        alias = "usld",
        about = "Update an existing swim lane definition"
    )]
    UpdateSwimLaneDefinition {
        #[structopt(long)]
        definition: String, // JSON string containing SwimLaneDefinitionExt
    },

    #[structopt(
        name = "get_all_swim_lanes",
        alias = "gsl",
        about = "Get all swim lanes"
    )]
    GetAllSwimLane,
}

#[derive(Debug, StructOpt)]
pub enum ZomeCommand {
    #[structopt(name = "whoami", alias = "w", about = "See your agent's public key")]
    WhoAmI,

    #[structopt(name = "ledger", alias = "l", about = "See your ledger")]
    GetLedger,

    #[structopt(
        name = "get_pending_transactions",
        alias = "p",
        about = "See all pending transactions"
    )]
    GetPending,

    #[structopt(
        name = "get_actionable_transactions",
        alias = "a",
        about = "See all actionable transactions"
    )]
    GetActionableTransactions,

    #[structopt(
        name = "get_completed_transactions",
        alias = "c",
        about = "See all completed transactions"
    )]
    GetCompleted,

    #[structopt(name = "create_spend", alias = "cp", about = "Create a spend")]
    CreateSpend {
        #[structopt(long)]
        receiver: String,

        #[structopt(long)]
        amount: String,

        #[structopt(long)]
        note: Option<String>,

        #[structopt(long)]
        auto_credit_check: Option<bool>,
    },

    #[structopt(name = "create_invoice", alias = "ci", about = "Create an invoice")]
    CreateInvoice {
        #[structopt(long)]
        spender: String,

        #[structopt(long)]
        amount: String,

        #[structopt(long)]
        note: Option<String>,
    },

    #[structopt(
        name = "accept",
        alias = "acc",
        about = "Accept to participate in a request to spend of receive funds"
    )]
    AcceptTransaction {
        #[structopt(long)]
        address: String,

        #[structopt(long)]
        auto_credit_check: Option<bool>,
    },

    #[structopt(
        name = "get_parked_spend",
        alias = "gp",
        about = "Get spends that you have parked"
    )]
    GetParkedSpend,

    #[structopt(name = "execute_rave", alias = "er", about = "Execute a RAVE request")]
    ExecuteRave {
        #[structopt(long)]
        input: String, // This will be a JSON string containing RaveExecuteInputs
    },

    #[structopt(
        name = "get_incoming_raves",
        alias = "gir",
        about = "See all requests to execute RAVE"
    )]
    GetIncomingRaves,

    #[structopt(
        name = "collect_from_rave",
        alias = "ar",
        about = "Accept a RAVE request"
    )]
    AcceptRave {
        #[structopt(long)]
        rave: String, // This will be a JSON string containing Transaction
    },

    #[structopt(
        name = "get_current_pool_definition",
        alias = "gpd",
        about = "See the current pool definitions"
    )]
    GetPoolDefinitions,

    #[structopt(
        name = "get_pool_pieces_details",
        alias = "gpd",
        about = "See current pool pieces details"
    )]
    GetPoolPiecesDetails,

    #[structopt(
        name = "get_swim_lanes",
        alias = "gsl",
        about = "See all swim lanes and their definitions"
    )]
    GetAllSwimLanes,

    #[structopt(
        name = "get_code_templates_lib",
        alias = "gct",
        about = "See all code templates in the library"
    )]
    GetCodeTemplatesLib,
}
