#include <mitmproxy_network.h>

void mitmproxyPlugin::connect()
{
    socket = new zmq::socket_t(context, zmq::socket_type::pair);
    int linger_time = 0;
    socket->set(zmq::sockopt::linger, linger_time);
    try {
        socket->bind(this->path);
    } catch (zmq::error_t err) {
        qDebug() << "failed binding socket" << err.what();
        error(err.what());
        throw;
    };
    is_connected = true;
    qDebug() << "connected";
}

void mitmproxyPlugin::reconnect()
{
    this->disconnect();
    this->connect();
}

QString mitmproxyPlugin::getName()
{
    return QString("mitmproxy bridge");
}

void mitmproxyPlugin::process()
{
    connect();
    while(true) {
        zmq::message_t response;
        const auto ret = socket->recv(response, zmq::recv_flags::dontwait);
        if(!ret) {
            continue;
        }
        json j;
        try {
            j = json::parse(response.to_string());
        } catch (nlohmann::detail::parse_error& err) {
            qDebug() << err.what();
            qDebug() << "malformed json received " << response.to_string().c_str();
        }
        //std::cout << std::setw(4) << j << "\n\n";
        std::string msg_type;
        if(!json_get(j, msg_type, "msg")) {
            qDebug() << "broken message received " << response.to_string().c_str();
        } else if(msg_type == "responseheaders") {
            qDebug() << "received " << msg_type.c_str();
        } else if(msg_type == "response") {
            qDebug() << "received " << msg_type.c_str();
            //qDebug() << "message: " << QString(response.to_string().c_str());
            emit message(j);
        } else if(msg_type == "requestheaders") {
            qDebug() << "received " << msg_type.c_str();
        } else if(msg_type == "request") {
            qDebug() << "received " << msg_type.c_str();
            qDebug() << "message: " << QString(response.to_string().c_str());
        } else if(msg_type == "ping") {
            qDebug() << "received " << msg_type.c_str();
        } else if(msg_type == "error") {
            qDebug() << "received " << msg_type.c_str();
            // websocket events
            emit error("error received");
        } else if(msg_type == "websocket_handshake") {
            qDebug() << "received " << msg_type.c_str();
        } else if(msg_type == "websocket_start") {
            qDebug() << "received " << msg_type.c_str();
            std::cout << std::setw(4) << j << "\n\n";
        } else if(msg_type == "websocket_message") {
            qDebug() << "received " << msg_type.c_str();
        } else if(msg_type == "websocket_end") {
            qDebug() << "received " << msg_type.c_str();
        } else if(msg_type == "websocket_error") {
        } else {
            qDebug() << "unknown or broken message type received: " << msg_type.c_str();
        }

        qDebug() << "sending ack";
        std::string m = "{\"msg\": \"ack\"}";
        socket->send(zmq::buffer(m.c_str(), m.length()), zmq::send_flags::dontwait);
    }
}

bool mitmproxyPlugin::connected()
{
    return is_connected;
}

void mitmproxyPlugin::disconnect()
{
    delete socket;
    is_connected = false;
    qDebug() << "disconnected";
}