#include "developer_console.hpp"

#include <iostream>

#include "util.hpp"

namespace developer {
    DeveloperConsole s_instance;

    DeveloperConsole::CallbackResult DeveloperConsole::CallbackResult::createError(const std::string &answer)
    {
        return CallbackResult(false, answer);
    }

    DeveloperConsole::CallbackResult DeveloperConsole::CallbackResult::createOkay(const std::string &answer)
    {
        return CallbackResult(true, answer);
    }

    DeveloperConsole::CallbackResult::CallbackResult(bool okay, const std::string &answer)
        : okay(okay), answer(answer)
    {
    }

    DeveloperConsole::DeveloperConsole()
    {
    }

    // static thing.
    DeveloperConsole &DeveloperConsole::instance() {
        return s_instance;
    }

    bool DeveloperConsole::addCallback(const std::string &token, callback_t cb)
    {
        bool hasWhitespace = false;
        for (size_t i=0; i<token.size(); i++) {
            if (isspace(token[i])) {
                hasWhitespace = true;
                break;
            }
        }

        bool cbIsNull   = (cb == nullptr);
        bool tokenEmpty = token.empty();

        if (hasWhitespace || cbIsNull || tokenEmpty) {
            std::cout << "not registering bad token/cb comibnation for:  " << token << std::endl;
            return false;
        }

        //std::cout<<"[developer console] adding developer "
        //    "callback for token '" << token << "'" << std::endl;

        m_callbacks[token] = cb;

        return true;
    }

    DeveloperConsole::CallbackResult DeveloperConsole::dispatchInput(const std::string &token, const std::string &payload)
    {
        std::map<std::string, DeveloperConsole::callback_t>::iterator it = m_callbacks.find(token);
        if (it == m_callbacks.end()) {
            return DeveloperConsole::CallbackResult::createError("unknown command with token: '" + token + "'");
        }

        return it->second(payload);
    }

    DeveloperConsole::CallbackResult resultOkay()
    {
        return DeveloperConsole::CallbackResult::createOkay();
    }
}
