#include "console_tab_helpers.h"

#include <algorithm>
#include <cctype>

namespace dragonx {
namespace ui {

namespace {
// First tokens (lowercase) of console/RPC commands that carry a secret argument on the command line.
// Output-secret commands (dumpprivkey / z_exportkey / z_exportmnemonic) are deliberately absent —
// their secret is in the RESULT, which is a separate redaction concern.
const char* const kSecretConsoleCommands[] = {
    "walletpassphrase", "walletpassphrasechange", "encryptwallet",
    "importprivkey", "importwallet", "importmulti",
    "z_importkey", "z_importviewingkey", "z_importwallet",
    "signrawtransaction", "magicrecoverkey", "sethdseed", "importmnemonic",
};

std::string firstConsoleTokenLower(const std::string& cmd, size_t& tokenEnd) {
    size_t b = cmd.find_first_not_of(" \t");
    if (b == std::string::npos) { tokenEnd = cmd.size(); return {}; }
    size_t e = cmd.find_first_of(" \t", b);
    tokenEnd = (e == std::string::npos) ? cmd.size() : e;
    std::string t = cmd.substr(b, tokenEnd - b);
    std::transform(t.begin(), t.end(), t.begin(),
                   [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
    return t;
}
} // namespace

float ComputeConsoleInputHeight(float frameHeightWithSpacing,
                                float itemSpacingY,
                                float spacingSm,
                                float spacingXs,
                                float cursorOffset)
{
    return spacingSm + itemSpacingY + frameHeightWithSpacing + spacingSm + spacingXs + cursorOffset;
}

float ComputeConsoleOutputHeight(float availableHeight,
                                 float inputHeight,
                                 float minHeight,
                                 float minHeightRatio)
{
    return std::max(availableHeight - inputHeight, std::max(minHeight, availableHeight * minHeightRatio));
}

float ClampConsoleWrapWidth(float contentWidth, float paddingX)
{
    return std::max(50.0f, contentWidth - paddingX * 2.0f);
}

bool ConsoleCommandCarriesSecret(const std::string& cmd)
{
    size_t end = 0;
    const std::string name = firstConsoleTokenLower(cmd, end);
    if (name.empty()) return false;
    for (const char* s : kSecretConsoleCommands) if (name == s) return true;
    return false;
}

std::string RedactConsoleCommand(const std::string& cmd)
{
    size_t end = 0;
    const std::string name = firstConsoleTokenLower(cmd, end);
    if (name.empty()) return cmd;
    bool secret = false;
    for (const char* s : kSecretConsoleCommands) if (name == s) { secret = true; break; }
    if (!secret) return cmd;
    // Only redact if there are actually arguments after the command name.
    if (cmd.find_first_not_of(" \t", end) == std::string::npos) return cmd;
    return cmd.substr(0, end) + " ****";
}

} // namespace ui
} // namespace dragonx
