--[[
    Core/Commands.lua

    Slash command surface: /shiny and /shinyhunter.

    Destructive actions never run on the first invocation. "/shiny reset" explains
    what it would erase and requires "/shiny reset confirm" to go through.

    The two SLASH_* variables and the SlashCmdList entry are globals because
    that is the interface Blizzard exposes; they are the only names this addon
    adds to _G besides the saved variables table and the main window frame.
]]

local _, ns = ...

local Commands = ns.NewModule("Commands")
ns.Commands = Commands

local handlers = {}

local function PrintHelp()
    local L = ns.L

    ns.Print(L["CMD_HELP_HEADER"])
    ns.Print(L["CMD_HELP_OPEN"])
    ns.Print(L["CMD_HELP_DEBUG"])
    ns.Print(L["CMD_HELP_DUMP"])
    ns.Print(L["CMD_HELP_VERSION"])
    ns.Print(L["CMD_HELP_VALIDATE"])
    ns.Print(L["CMD_HELP_STABLE"])
    ns.Print(L["CMD_HELP_SIGHTINGS"])
    ns.Print(L["CMD_HELP_RESET"])
    ns.Print(L["CMD_HELP_HELP"])
end

handlers.help = PrintHelp
handlers["?"] = PrintHelp

handlers.debug = function(argument, extra)
    if argument == "dump" then
        ns.Debug:Dump(tonumber(extra))
        return
    end

    local enabled = not ns.Debug:IsEnabled()
    ns.Debug:SetEnabled(enabled)
    ns.Config:Set("debugEnabled", enabled)
    ns.Print(enabled and ns.L["DEBUG_ON"] or ns.L["DEBUG_OFF"])
end

handlers.version = function()
    local clientVersion, _, _, interfaceVersion = GetBuildInfo()
    ns.Print(ns.L["VERSION_INFO"]:format(ns.version, clientVersion, tostring(interfaceVersion)))
end

handlers.validate = function()
    ns.Data.Validator:PrintReport()
    ns.Data.Tests:PrintResults()
end

handlers.sightings = function()
    ns.Collection.SightingTracker:PrintReport()
end

handlers.stable = function()
    ns.Collection.StableScanner:PrintReport()
end

handlers.reset = function(argument)
    if argument ~= "confirm" then
        ns.Print(ns.L["RESET_CONFIRM"])
        return
    end

    ns.Database:ResetAll()
    ns.Config:ApplyStoredSettings()
    ns.Print(ns.L["RESET_DONE"])
end

local function Dispatch(input)
    -- Split into at most three words. Anything beyond is ignored rather than
    -- failing to match, so a fat-fingered "/shiny debug dump 20 please" still
    -- does the sensible thing.
    local command, rest = input:lower():match("^%s*(%S*)%s*(.-)%s*$")
    local argument, extra = rest:match("^(%S*)%s*(%S*)")

    if command == "" then
        ns.UI.MainWindow:Toggle()
        return
    end

    local handler = handlers[command]
    if handler then
        handler(argument, extra)
    else
        ns.Print(ns.L["CMD_UNKNOWN"]:format(command))
    end
end

--- Installs the slash commands. Called once during start-up.
function Commands:OnInitialize()
    SLASH_SHINYHUNTER1 = "/shiny"
    SLASH_SHINYHUNTER2 = "/shinyhunter"

    SlashCmdList["SHINYHUNTER"] = function(input)
        Dispatch(input or "")
    end

    ns.Debug:Log("CMD", "slash commands registered")
end
