
#include "curlpp/Options.hpp"
#include "kubecontrol/KubePod.hpp"
#include "kubecontrol/KubernetesAPI.hpp"
#include "nlohmann/json_fwd.hpp"
#include <cstddef>
#include <cstdlib>
#include <exception>
#include <kubecontrol/PodController.hpp>
#include <math.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include "loguru.hpp"


namespace kubecontrol
{
    PodController::PodController(std::string pathToKubectlConfig):
    APIInterface_( YAML::LoadFile(pathToKubectlConfig))
    {
        
        ApiCall_ = "/api/v1/namespaces/"+APIInterface_.getNamespace()+"/pods/";
       
    }

    std::string PodController::getServerAddress()
    {
        return APIInterface_.getAddress();
    }

    KubernetesAPI PodController::getKubernetesAPI()
    {
        return APIInterface_;
    }




    void PodController::startPod(KubePod Pod,bool WaitTillRunning )
    {

        LOG_S(INFO)<< "starting pod: "<<Pod.getUUID();
        // auto response = Pod.start(ServerAddress_+ApiCall_, BearerToken_,WaitTillRunning);
        auto response = Pod.start(APIInterface_,WaitTillRunning);

        std::lock_guard<std::mutex>lock(mx_);
        PodList_.emplace_back(std::make_unique<KubePod>(Pod));
        // LOG_S(INFO)<<response;
    }


    void PodController::startPod(std::shared_ptr<KubePod> Pod,bool WaitTillRunning )
    {
         LOG_S(INFO)<< "starting pod: "<<Pod->getUUID();
        // auto response = Pod.start(ServerAddress_+ApiCall_, BearerToken_,WaitTillRunning);
        auto response = Pod->start(APIInterface_,WaitTillRunning);

        std::lock_guard<std::mutex>lock(mx_);
        PodList_.emplace_back(std::make_unique<KubePod>(*Pod));
    }


    void PodController::stopPod(std::string uuid)
    {
        std::lock_guard<std::mutex>lock(mx_);
        // PodList_
         for (std::vector<std::unique_ptr<KubePod>>::iterator it = PodList_.begin(); it != PodList_.end();) 
        {   
        
           if (uuid == it->get()->getUUID())
           {
            it->get()->stop(APIInterface_);
            it = PodList_.erase(it);
}
            else 
            {
             it++;
            }
        }

    }

    void PodController::stopAllPods()
    {   
        std::lock_guard<std::mutex>lock(mx_);

        for (auto &item : PodList_) 
        {
            item->stop(APIInterface_);

            LOG_S(INFO)<< "stopping pod: "<<item->getUUID();
        }

        PodList_.clear();
    }

   
   std::vector<PodInfos> PodController::getInfoForAllPods()
    {
        std::vector<PodInfos> infosOfAllPods;
         for (auto &item : PodList_) 
        {
            if(item->updateInfoForThisPod(APIInterface_) == 0 )
            {
               infosOfAllPods.emplace_back(extractInfosFromKubePod(item.get()));
            }

        }

        return infosOfAllPods;

    
    }


    PodInfos PodController::getInfoForPod(std::string uuid)
    {
        PodInfos info;
          for (auto &item : PodList_) 
        {
            if(item->getUUID() == uuid )
            {
                LOG_S(INFO)<<"pod found: "<< item->getUUID();
                item->updateInfoForThisPod(APIInterface_); 
               return extractInfosFromKubePod(item.get());
            }

        }
        return info;
      
    }


    PodInfos PodController::extractInfosFromKubePod(KubePod * pod)
    {
            PodInfos info;
            info.UUID = pod->getUUID();
            info.Owner = pod->getOwner();
            info.Component =pod->getComponent();
            info.IP = pod->getIp();
            info.Status = pod->getStatus();
            info.Childs  = pod->getPodsChilds(APIInterface_);

        return info;
    }


    

   
   

    



    // std::string PodController::performRequest(std::string curlURL)
    // {

    //     std::string AuthString = "Authorization: Bearer " + BearerToken_;

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

    //     auto request = std::make_unique<curlpp::Easy>();

        
    //     // request->setOpt(test);
    //     std::stringstream result;
    //     request->setOpt(cURLpp::Options::WriteStream(&result));

    //     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();
        
    //     // std::string response = mWriterChunk.getResponse();
    //     std::string response = result.str();
    //     return response;
    // }

    




}