#include "client.h"
#include <iostream>
#include <of_str.h>

using namespace ofen;
CClient::CClient(const std::shared_ptr<spdlog::logger>& logger) : logger_(logger)
{
    client_ = std::make_shared<CTcpClient>(io_context_, logger_);
    supported_.push_back("Get");
}

CClient::~CClient()
{
}

void CClient::run()
{
    if (!client_->connect("127.0.0.1", "8080")) {
        logger_->info("{} connect err.", __FUNCTION__);
        return;
    }
    client_->register_func([&](CFrameBuffer* buf) { handle_frame(buf); });
    client_->async_recv();
    std::thread thread([&]() { io_context_.run(); });
    char line[512]{};
    while (std::cin.getline(line, 512)) {
        std::string cmd_input(line);
        if (std::strstr(line, "end")) {
            break;
        }
        auto vec = COfStr::split(cmd_input, " ");
        if (vec.size() < 1) {
            logger_->error("input's invalid format.");
            continue;
        }
        std::string cmd{};
        std::string param{};
        if (vec.size() == 1) {
            cmd = vec[0];
        }
        else {
            cmd = vec[0];
            param = vec[1];
        }
        if (cmd == "Get") {
            get_task_list();
            continue;
        }
        if (cmd == "Down") {
            int key = param.empty() ? -1 : std::stoi(param);
            if (task_list_.count(key)) {
                down_task();
            }
            else {
                logger_->error("no task number find.");
            }
            continue;
        }
        if (cmd == "Up") {
            continue;
        }
        logger_->error("No matched cmd.");
    }
    client_->disconnect();
    thread.join();
    logger_->info("{} exit.", __FUNCTION__);
}

bool CClient::get_task_list()
{
    char* send = nullptr;
    int len{};
    std::shared_ptr<CFrameBuffer> buf = std::make_shared<CFrameBuffer>();
    buf->data_ = new char[512]{};
    auto flen = std::snprintf(buf->data_, 512, "%s", gGet);
    buf->len_ = flen;
    buf->type_ = 199;
    if (!CTransProtocal::pack(buf.get(), &send, len)) {
        logger_->error("{} pack failed.", __FUNCTION__);
        return false;
    }
    if (!client_->send(send, len)) {
        return false;
    }
    delete[] send;
    return true;
}

bool CClient::get_clients()
{
    return false;
}

bool CClient::down_task()
{
    return false;
}

bool CClient::up_task()
{
    return false;
}

void CClient::handle_frame(CFrameBuffer* buf)
{
    if (buf == nullptr) {
        logger_->error("{} nullptr.", __FUNCTION__);
        return;
    }
    // logger_->debug("type: {}", buf->type_);
    // logger_->debug("len: {}", buf->len_);

    if (buf->type_ == 199) {
        task_list_.clear();
        std::string source(buf->data_);
        int index = 0;
        auto vec = COfStr::split(source, "|");
        for (const auto& item : vec) {
            task_list_[index] = item;
            ++index;
            logger_->warn("{}:{}", index, item);
        }
    }
}
