#include <nlohmann/json.hpp>

#include <SimControl/PodList.hpp>
#include <loguru.hpp>
#include <memory>
#include <utility>



namespace SimControl 
{
            PodList::PodList()
            {


            }



            PodList::PodList(std::string jsonstring)
            {   
               
                addPodsFromString(jsonstring);


            }

            void PodList::addPodsFromString(std::string respond)
            {
                nlohmann::json j;
                try 
                {
                    j = nlohmann::json::parse(respond);
                    if (j.contains("items")) 
                    {
                    int i = j["items"].size();
                        for (int a = 0; a<i; a++) 
                        {  
                        auto item = std::make_shared<PodListItem>();
                        item->Uuid = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/name"].get<std::string>();
                        item->Component = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/component"].get<std::string>();
                        item->Image = j["items"][a]["spec"]["containers"][0]["image"].get<std::string>();
                        item->Ip = j["items"][a]["status"]["podIP"].get<std::string>();
                        item->Status = j["items"][a]["status"]["phase"].get<std::string>();
                        item->PartOf =  j["items"][a]["metadata"]["labels"]["app.kubernetes.io/part-of"].get<std::string>();
                        // LOG_S(INFO)<<j["items"][a]["status"]["podIP"];

                        // LOG_S(INFO)<<j["items"][a]["status"]["phase"];
                        this->addPodToList(item);
                        }


                        i = j["items"].size();
                        for (int a = 0; a<i; a++) 
                        {  
                        auto item = std::make_shared<PodListItem>();
                            std::string uuid = j["items"][a]["metadata"]["labels"]["app.kubernetes.io/name"].get<std::string>();
                            std::string parentName= j["items"][a]["metadata"]["labels"]["app.kubernetes.io/part-of"].get<std::string>();

                            auto self = this->getPod(uuid);
                            auto parent = this->getPod(parentName);
                            if (parent != nullptr && self != nullptr) {      
                              parent->relatedPods.emplace_back(std::make_pair(self->Uuid, self));
                            }else if (parent== nullptr) 
                            {
                                self->PartOf = parentName;
                            }

                        }
                    }


                } catch (std::exception& e) 
                {
                    LOG_S(ERROR)<<e.what();
                }

            }


            void  PodList::addPodToList(std::shared_ptr<PodListItem> pod)
            {

                podList_.insert_or_assign(pod->Uuid,pod);

            }

            void PodList::addPodToList(std::string respond)
            {

                addPodsFromString(respond);
            }



            std::shared_ptr<PodListItem>  PodList::getPod(std::string uuid)
            {
                for(auto item : podList_)
                {
                    if (item.first == uuid)
                    {
                    return item.second;
                    }
                }
                return nullptr;
            }

            bool  PodList::removePod(std::string uuid)
            {
                for(auto it = podList_.begin(); it != podList_.end();)
                {
                    if (it->first == uuid)
                    {
                        it = podList_.erase(it);
                        return true; 
                    }
                }
                return false;
            }

            std::vector<std::string> PodList::getPodsUUID()
            {
                std::vector<std::string> list;
                LOG_S(INFO)<< podList_.size();
                for(auto item : podList_)
                {
                    list.emplace_back(item.first);
                }
                return list;    
            }


            nlohmann::json  PodList::getPodTree(std::string uuid)
            {
                LOG_S(INFO)<<uuid;
                nlohmann::json j;
                auto pod = this->getPod(uuid);
                if (pod!= nullptr) 
                {
                    j["UUID"] = pod->Uuid;
                    j["IMAGE"] = pod->Image;
                    j["IP"] = pod->Ip;
                    j["COMPONENT"] = pod->Component;

                    int i = 0;
                    for (auto item:pod->relatedPods) 
                    {   
                    
                        j["RELATIVES"][i]["UUID"] = item.second->Uuid;
                        j["RELATIVES"][i]["IMAGE"] = item.second->Image;
                        j["RELATIVES"][i]["IP"] = item.second->Ip;
                        j["RELATIVES"][i]["COMPONENT"] = item.second->Component;
                        j["RELATIVES"][i]["PART-OF"] = item.second->PartOf;

                        i++;
                    }
                }

                return j;

            }
            
            size_t PodList::size()
            {
                return podList_.size();
            }




}