#include "console_command_reference.h"

#include <cstddef>

namespace dragonx {
namespace ui {

namespace {

template <size_t N>
constexpr int CountOf(const ConsoleCommandEntry (&)[N])
{
    return static_cast<int>(N);
}

const ConsoleCommandEntry kControlCommands[] = {
    {"help", "List all commands, or get help for a specified command", "[\"command\"]"},
    {"getinfo", "Get general info about the node", ""},
    {"stop", "Stop the daemon", ""},
};

const ConsoleCommandEntry kNetworkCommands[] = {
    {"getnetworkinfo", "Return P2P network state info", ""},
    {"getpeerinfo", "Get data about each connected peer", ""},
    {"getconnectioncount", "Get number of peer connections", ""},
    {"getnettotals", "Get network traffic statistics", ""},
    {"addnode", "Add, remove, or connect to a node", "\"node\" \"add|remove|onetry\""},
    {"setban", "Add or remove an IP/subnet from the ban list", "\"ip\" \"add|remove\" [bantime] [absolute]"},
    {"listbanned", "List all banned IPs/subnets", ""},
    {"clearbanned", "Clear all banned IPs", ""},
    {"ping", "Ping all peers to measure round-trip time", ""},
};

const ConsoleCommandEntry kBlockchainCommands[] = {
    {"getblockchaininfo", "Get current blockchain state", ""},
    {"getblockcount", "Get number of blocks in longest chain", ""},
    {"getbestblockhash", "Get hash of the tip block", ""},
    {"getblock", "Get block data for a given hash or height", "\"hash|height\" [verbosity]"},
    {"getblockhash", "Get block hash at a given height", "height"},
    {"getblockheader", "Get block header for a given hash", "\"hash\" [verbose]"},
    {"getdifficulty", "Get proof-of-work difficulty", ""},
    {"getrawmempool", "Get all txids in mempool", "[verbose]"},
    {"getmempoolinfo", "Get mempool state info", ""},
    {"gettxout", "Get details about an unspent output", "\"txid\" n [includemempool]"},
    {"coinsupply", "Get coin supply information", "[height]"},
    {"getchaintips", "Get all known chain tips", ""},
    {"getchaintxstats", "Get chain transaction statistics", "[nblocks] [\"blockhash\"]"},
    {"verifychain", "Verify the blockchain database", "[checklevel] [numblocks]"},
    {"kvsearch", "Search the blockchain key-value store", "\"key\""},
    {"kvupdate", "Update a key-value pair on-chain", "\"key\" \"value\" days"},
};

const ConsoleCommandEntry kMiningCommands[] = {
    {"getmininginfo", "Get mining-related information", ""},
    {"setgenerate", "Turn mining on or off  (true/false [threads])", "generate [genproclimit]"},
    {"getgenerate", "Check if the node is mining", ""},
    {"getnetworkhashps", "Get estimated network hash rate", "[blocks] [height]"},
    {"getblocksubsidy", "Get block reward at a given height", "[height]"},
    {"getblocktemplate", "Get block template for mining", "[\"jsonrequestobject\"]"},
    {"submitblock", "Submit a mined block to the network", "\"hexdata\""},
};

const ConsoleCommandEntry kWalletCommands[] = {
    {"getbalance", "Get wallet transparent balance", "[\"account\"] [minconf]"},
    {"z_gettotalbalance", "Get total transparent + shielded balance", "[minconf]"},
    {"z_getbalances", "Get all balances (transparent + shielded)", ""},
    {"getnewaddress", "Generate a new transparent address", ""},
    {"z_getnewaddress", "Generate a new shielded address", "[\"type\"]"},
    {"listaddresses", "List all transparent addresses", ""},
    {"z_listaddresses", "List all z-addresses", ""},
    {"sendtoaddress", "Send to a specific address", "\"address\" amount"},
    {"z_sendmany", "Send to multiple z/t-addresses with shielded support", "\"fromaddress\" [{\"address\":\"...\",\"amount\":...}]"},
    {"z_shieldcoinbase", "Shield transparent coinbase funds to a z-address", "\"fromaddress\" \"tozaddress\" [fee] [limit]"},
    {"z_mergetoaddress", "Merge multiple UTXOs/notes to one address", "[\"fromaddress\",...] \"toaddress\" [fee] [limit]"},
    {"listtransactions", "List recent wallet transactions", "[\"account\"] [count] [from]"},
    {"listunspent", "List unspent transaction outputs", "[minconf] [maxconf]"},
    {"z_listunspent", "List unspent shielded notes", "[minconf] [maxconf]"},
    {"z_getoperationstatus", "Get status of async z operations", "[\"operationid\",...]"},
    {"z_getoperationresult", "Get result of completed z operations", "[\"operationid\",...]"},
    {"z_listoperationids", "List all async z operation IDs", ""},
    {"getwalletinfo", "Get wallet state info", ""},
    {"backupwallet", "Back up wallet to a file", "\"destination\""},
    {"dumpprivkey", "Dump private key for an address", "\"address\""},
    {"importprivkey", "Import a private key into the wallet", "\"privkey\" [\"label\"] [rescan]"},
    {"dumpwallet", "Dump all wallet keys to a file", "\"filename\""},
    {"importwallet", "Import wallet from a dump file", "\"filename\""},
    {"z_exportkey", "Export spending key for a z-address", "\"zaddr\""},
    {"z_importkey", "Import a z-address spending key", "\"zkey\" [rescan] [startheight]"},
    {"z_exportviewingkey", "Export viewing key for a z-address", "\"zaddr\""},
    {"z_importviewingkey", "Import a z-address viewing key", "\"vkey\" [rescan] [startheight]"},
    {"z_exportwallet", "Export all wallet keys (including z-keys) to file", "\"filename\""},
    {"signmessage", "Sign a message with an address key", "\"address\" \"message\""},
    {"settxfee", "Set the transaction fee per kB", "amount"},
    {"walletpassphrase", "Unlock the wallet with passphrase", "\"passphrase\" timeout"},
    {"walletlock", "Lock the wallet", ""},
    {"encryptwallet", "Encrypt the wallet with a passphrase", "\"passphrase\""},
};

const ConsoleCommandEntry kRawTransactionCommands[] = {
    {"createrawtransaction", "Create a raw transaction spending given inputs", "[{\"txid\":\"...\",\"vout\":n},...] {\"address\":amount,...}"},
    {"decoderawtransaction", "Decode raw transaction hex string", "\"hexstring\""},
    {"decodescript", "Decode a hex-encoded script", "\"hex\""},
    {"getrawtransaction", "Get raw transaction data by txid", "\"txid\" [verbose]"},
    {"sendrawtransaction", "Submit raw transaction to the network", "\"hexstring\" [allowhighfees]"},
    {"signrawtransaction", "Sign a raw transaction with private keys", "\"hexstring\""},
    {"fundrawtransaction", "Add inputs to meet output value", "\"hexstring\""},
};

const ConsoleCommandEntry kUtilityCommands[] = {
    {"validateaddress", "Validate a transparent address", "\"address\""},
    {"z_validateaddress", "Validate a z-address", "\"zaddr\""},
    {"estimatefee", "Estimate fee for a transaction", "nblocks"},
    {"verifymessage", "Verify a signed message", "\"address\" \"signature\" \"message\""},
    {"createmultisig", "Create a multisig address", "nrequired [\"key\",...]"},
    {"invalidateblock", "Mark a block as invalid", "\"hash\""},
    {"reconsiderblock", "Reconsider a previously invalidated block", "\"hash\""},
};

} // namespace

const std::vector<ConsoleCommandCategory>& consoleCommandCategories()
{
    static const std::vector<ConsoleCommandCategory> categories = {
        {"Control",          kControlCommands,        CountOf(kControlCommands)},
        {"Network",          kNetworkCommands,        CountOf(kNetworkCommands)},
        {"Blockchain",       kBlockchainCommands,     CountOf(kBlockchainCommands)},
        {"Mining",           kMiningCommands,         CountOf(kMiningCommands)},
        {"Wallet",           kWalletCommands,         CountOf(kWalletCommands)},
        {"Raw Transactions", kRawTransactionCommands, CountOf(kRawTransactionCommands)},
        {"Utility",          kUtilityCommands,        CountOf(kUtilityCommands)},
    };
    return categories;
}

} // namespace ui
} // namespace dragonx
