---
--- Date         : 2020-07-15 10:16:01
--- Author       : LICHAO7
--- LastEditors  : LICHAO7
--- LastEditTime : 2020-08-04 10:12:45
--- Description  : The command parser
---

local CMD_MAP = ImportScript("ugc_common/script/cases/ingame_console/cmd_map.lua").CMD_MAP;

--- *Special methods start* ---

---
--- 帮助消息
---
CMD_MAP.GetHelpText = function()
    local strHelp = [[
GM command syntax: CommandName,[param 1, param 2, ...]
E.G.
   There is now a function for moving roles, called "Move to",
and it takes three arguments, X,Y, and Z,Then its command is:
move to,100,150,0
    ]];
    return strHelp;
end

---
--- 未找到命令消息
---
CMD_MAP.CMDNotFound = function()
    local str404 = [[
GM connand not found.
Check that the command is registered correctly,
or that the command name was entered correctly.
    ]];
    return str404;
end

---
--- 执行Lua
--- @param script string
--- @return string
---
CMD_MAP.Lua = function(script)
    local fnCmd = loadstring(script);
    local errhandle = function(e)
        local estr = "Call Lua script text failed. error is:" .. tostring(e);
        LOG_E("[CMD]" .. estr);
        return estr;
    end
    local status = false;
    local msg = "";
    local strRet = "[INFO][Lua]Ret: ";

    if type(fnCmd) == "function" then
        status, msg = xpcall(fnCmd, errhandle);
    else
        msg = "Load script text error.";
    end
    if not status then
        strRet = "[ERROR][Lua]" .. tostring(msg);
    else
        strRet = strRet .. tostring(msg);
    end
    return strRet;
end

--- *Special methods end* ---

---
--- helper function
---
--- @protected
--- @type table
---
local Heper = {
    IsStrSplitEmpty = function(parts)
        return parts and #parts == 1 and parts[1] == "\0";
    end
};

Parser = {
    CMD_MAP = CMD_MAP
};

---
--- 解析命令字符串
---
--- @param str_cmd string
--- @return function table, string, string
---
Parser.Parse = function(str_cmd)
    -- local cmdPos    = string.find(str_cmd, ",") or string.find(str_cmd, "\0") or 0;
    -- local strCmd    = string.sub(str_cmd, 0, cmdPos - 1);
    -- local strParams = string.sub(str_cmd, cmdPos + 1, string.find(str_cmd, "\0") - 1 or -1);
    local fnCmd     = nil;
    local tabParams = {};
    local tabTextSplits = string.split(str_cmd, ",");
    local strCmd    = table.remove(tabTextSplits, 1);
    local strParams = table.concat(tabTextSplits, ",");

    -- params
    for key, value in ipairs(tabTextSplits) do
        table.insert(tabParams, string.trim(value));
    end

    -- if help cmd
    if strCmd == 'help' or strCmd == '\\help' or strCmd == "/help" or strCmd == "/h" or strCmd == "\\h" then
        strCmd = "GetHelpText";
    end
    if string.lower(strCmd) == "lua" then
        tabParams = {
            strParams
        };
    end

    -- cmd
    fnCmd = CMD_MAP[strCmd];
    if type(fnCmd) ~= "function" then
        fnCmd = CMD_MAP["CMDNotFound"];
    end
    return fnCmd, tabParams, strCmd, strParams;
end

---
--- 获取CMD 字符串打包`table`
---
--- @return table
---
Parser.GetCMDStr = function()
    local tabCmdStr = {};
    for key, value in pairs(CMD_MAP) do
        local nParams = debug.getinfo(value, "u").nparams or 0;
        local i = 1;
        local tabCmdHelp = {
            name = "", param = ""
        };
        local tabCmdParam = {};
        while i <= nParams do
            table.insert(tabCmdParam, debug.getlocal(value, i) or "");
            i = i + 1;
        end
        tabCmdHelp.name  = key;
        tabCmdHelp.param = table.concat(tabCmdParam, ",");
        table.insert(tabCmdStr, tabCmdHelp);
    end
    return tabCmdStr;
end
