#include "server/commands/CommandUtils.h"

static bool splitStringIntern(const std::string& rawCommand, std::string& command, std::vector<std::string>& args)
{
    size_t old = 0;
    size_t index = 0;
    
    // parse first argument
    while(index < rawCommand.size())
    {
        if(rawCommand[index] == ' ')
        {
            command = rawCommand.substr(old, index - old);
            old = index + 1;
            index++;
            break;
        }
        index++;
    }
    // if the command name is the whole raw command
    if(index == rawCommand.size())
    {
        command = rawCommand.substr(old, index - old);
        return false;
    }
    
    // parse remainding arguments
    while(index < rawCommand.size())
    {
        if(rawCommand[index] == '"')
        {
            // no space before the quotation mark
            if(index != old) 
            {
                return true;
            }
            old = index + 1;
            while(true)
            {
                index++;
                // quotation mark not closed
                if(index >= rawCommand.size())
                {
                    return true;
                }
                else if(rawCommand[index] == '"')
                {
                    break;
                }
            }
            // no space after quotation mark
            if(index + 1 < rawCommand.size() && rawCommand[index + 1] != ' ') 
            {
                return true;
            }
            args.push_back(rawCommand.substr(old, index - old));
            old = index + 2;
        }
        else if(rawCommand[index] == ' ')
        {
            if(index > old && index - old > 0)
            {
                args.push_back(rawCommand.substr(old, index - old));
            }
            old = index + 1;
        }
        index++;
    }
    
    if(index > old && index - old > 0)
    {
        args.push_back(rawCommand.substr(old, index - old));
    }
    
    return false;
}

bool CommandUtils::splitString(const std::string& rawCommand, std::string& command, std::vector<std::string>& args)
{
    bool b = splitStringIntern(rawCommand, command, args);
    if(b)
    {
        args.clear();
        command = "";
    }
    return b;
}