
#include <cstddef>
#include <cstdlib>
#include <kubecontrol/PodController.hpp>
#include <string>


namespace kubecontrol
{
    PodController::PodController(std::string pathToKubectlConfig)
    {
         YAML::Node config = YAML::LoadFile(pathToKubectlConfig);
        
        BearerToken_ = config["users"][0]["user"]["token"].as<std::string>();

        char * KUBERNETES_SERVICE_HOST = std::getenv("KUBERNETES_SERVICE_HOST");
        char * KUBERNETES_SERVICE_PORT = std::getenv("KUBERNETES_SERVICE_PORT");

        if (KUBERNETES_SERVICE_HOST != nullptr && KUBERNETES_SERVICE_PORT!= nullptr) 
        {
            ServerAddress_ = std::string(KUBERNETES_SERVICE_HOST)+":"+std::string(KUBERNETES_SERVICE_PORT);
        } else
        {
            LOG_S(INFO)<<"Taking Serveraddress out of the provided YAML file";

            ServerAddress_ = config["clusters"][0]["cluster"]["server"].as<std::string>();
        }   

        ApiCall_ = "/api/v1/namespaces/hwinkel/pods/";
    }

    std::string PodController::getServerAddress()
    {
        return this->ServerAddress_;
    }



    void PodController::startPod(KubePod Pod)
    {
        PodList_.emplace_back(Pod);
        LOG_S(INFO)<< "starting pod: "<<Pod.getUUID();

        Pod.start(ServerAddress_+ApiCall_, BearerToken_);

    }

    void PodController::stopPod(std::string Label)
    {
        for (auto item : PodList_) 
        {
            if (Label == item.getLabel()) 
            {
                item.stop(ServerAddress_+ApiCall_, BearerToken_);
            }
        }

    }

    void PodController::stopAllPods()
    {
        for (auto item : PodList_) 
        {
            item.stop(ServerAddress_+ApiCall_, BearerToken_);
            LOG_S(INFO)<< "stopping pod: "<<item.getUUID();
        }
    }


    std::string PodController::getPodsInfo()
    {
    std::string curlURL = ServerAddress_+ApiCall_;
    std::string AuthString = "Authorization: Bearer " + BearerToken_;

    std::list<std::string> headers;
    headers.push_back(AuthString);

    curlpp::Easy request;

    WriterMemoryClass mWriterChunk;  
    curlpp::types::WriteFunctionFunctor functor = std::bind(&WriterMemoryClass::WriteMemoryCallback, &mWriterChunk, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
    curlpp::options::WriteFunction *test = new curlpp::options::WriteFunction(functor);
    request.setOpt(test);
    
    request.setOpt(new curlpp::options::HttpHeader(headers));

    request.setOpt(new curlpp::options::Url(curlURL));
    // request.setOpt(new curlpp::options::SslEngineDefault());
    // request.setOpt(new curlpp::options::CaPath("config/ca.crt"));
    request.setOpt(new curlpp::options::SslVerifyPeer(false));


    // request.setOpt(new curlpp::options::Verbose(true));


    request.perform();
    auto response = mWriterChunk.getResponse();

    auto j = nlohmann::json::parse(response);
    return j.dump();
    }


    std::string PodController::getInfoForPod(std::string Label)
    {
        for (auto item : PodList_) 
        {
            if (Label == item.getLabel()) 
            {
                return item.getInfo(ServerAddress_+ApiCall_, BearerToken_);
            }
        }
        return nullptr;
    }


}