#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;
}