#include "SimCore/SimCore.hpp"
#include "nlohmann/json_fwd.hpp"
#include <SimControl/Tracklist.hpp>




namespace SimControl 
{
     
            TrackList::TrackList()
            {

                TrackStore_ =  std::map<std::string, std::shared_ptr<SimCore::SimTrack>>();
            }

            void TrackList::addTrack(std::shared_ptr<SimCore::SimTrack> Track)
            {
                std::lock_guard<std::mutex> lock(mx_);
                
                auto [iterator, inserted] = TrackStore_.try_emplace(Track->getIdentifier().getUUID(),Track);
                if (!inserted) { iterator->second = Track; }


            }
            std::shared_ptr<SimCore::SimTrack> TrackList::getTrack(const SimCore::Identifier ID)
            {
               std::lock_guard<std::mutex> lock(mx_);

               auto it =  TrackStore_.find(ID.getUUID());
               return it->second;
            }

            std::shared_ptr<SimCore::SimTrack> TrackList::getTrackBySringID(std::string ID)
            {
                std::lock_guard<std::mutex> lock(mx_);

               auto it =  TrackStore_.find(ID);
               return it->second;
            }


           void TrackList::getJsonTRackList(nlohmann::json &message)
            {
                std::lock_guard<std::mutex> lock(mx_);
                try {
               for (std::map<std::string, std::shared_ptr<SimCore::SimTrack>>::iterator it=TrackStore_.begin(); it!=TrackStore_.end(); ++it)
               {
                    nlohmann::json j;
                    j["id"] = it->first;
                    j["Name"] = it->second->Name.getValue();
                    j["Course"] = it->second->Course.getValue();
                    j["Speed"] = it->second->Speed.getValue();
                    j["External"] = false;
                    j["Position"] = {it->second->getPosition().getGeodesicPos()[SimCore::LATITUDE], it->second->getPosition().getGeodesicPos()[SimCore::LONGITUDE]};
                    j["Height"] = it->second->getPosition().getGeodesicPos()[SimCore::HEIGHT];
                    j["Type"] = SimCore::Kind::EntityKindMap[it->second->EntityKind.getValue()];
                    j["Side"] = SimCore::Side::EntitySideMap[it->second->EntitySide.getValue()];

                    message["Entities"].push_back(j);
               }
                }catch (const std::exception e) {
                    LOG_S(ERROR)<< e.what();
                }
            }


       
}