#include "CommandParser.h"

bool CommandParser::parse(const EncodedString & command)
{
    std::vector<uint8_t> current_arg;
    EncodedString::iterator end = command.end();
    EncodedString::iterator it = command.begin();
    uint32_t quote = 0u;
    bool arg_content = false;
    auto append_char = [&current_arg, &it, &command, &arg_content]() {
        size_t offset = it.offset();
        for (size_t i = 0u, sz = it.size(); i < sz; i++)
        {
            current_arg.push_back(command[offset + i]);
        }
        arg_content = true;
    };
    auto collect_arg = [this, &current_arg, &arg_content] {
        if (arg_content)
        {
            m_args.push_back(EncodedString(&current_arg[0], current_arg.size()));
            current_arg.clear();
            arg_content = false;
        }
        arg_content = false;
    };
    while (it != end)
    {
        uint32_t cp = *it;
        if (cp == '\n')
        {
            /* Skip newline character */
        }
        else if ((quote != 0u) && (cp == quote))
        {
            quote = 0u;
        }
        else if ((quote == 0u) && ((cp == '\'') || (cp == '"')))
        {
            quote = cp;
            arg_content = true;
        }
        else if (cp == '\\')
        {
            if (++it == end)
            {
                m_parse_error = "Unterminated escape sequence";
                return false;
            }
            append_char();
        }
        else if ((cp == ' ') && (quote == 0u))
        {
            collect_arg();
        }
        else
        {
            append_char();
        }
        ++it;
    }

    if (quote != 0u)
    {
        m_parse_error = std::string("Unterminated quoted region");
        return false;
    }

    collect_arg();

    return true;
}
