#include "globals.h"

namespace maps::mrc::agent_proxy {

Globals::Globals(const common::Config& config,
                 const road_graph::Graph& roadGraph,
                 const succinct_rtree::Rtree& roadGraphRTree,
                 const fb::GraphReader& graphCoverage,
                 const NGeobase::TLookup& geobaseLookup,
                 ugc_event_logger::Logger& ugcEventLogger,
                 IWikiEditorClient& wikiEditorClient,
                 ISuncalcPtr suncalcPtr)
    : resultsQueue_(config.signalsUploader().queuePath())
    , poolHolder_(config.makePoolHolder())
    , mdsClient_(makeMdsClient(config))
    , roadGraph_(roadGraph)
    , roadGraphRTree_(roadGraphRTree)
    , graphCoverage_(graphCoverage)
    , geobaseLookup_(geobaseLookup)
    , ugcEventLogger_(ugcEventLogger)
    , wikiEditorClient_(wikiEditorClient)
    , suncalcPtr_(std::move(suncalcPtr))
{
}

void Globals::initialize(const common::Config& config,
                         const road_graph::Graph& roadGraph,
                         const succinct_rtree::Rtree& roadGraphRTree,
                         const fb::GraphReader& graphCoverage,
                         const NGeobase::TLookup& geobaseLookup,
                         ugc_event_logger::Logger& ugcEventLogger,
                         IWikiEditorClient& wikiEditorClient,
                         ISuncalcPtr suncalcPtr)
{
    instanceHolder().reset(new Globals(config,
                                       roadGraph,
                                       roadGraphRTree,
                                       graphCoverage,
                                       geobaseLookup,
                                       ugcEventLogger,
                                       wikiEditorClient,
                                       std::move(suncalcPtr)));
}

Globals& Globals::instance()
{
    GlobalsHolder& holder = instanceHolder();
    REQUIRE(holder, "Instance is not initialized");
    return *holder;
}

mds::Mds Globals::makeMdsClient(const common::Config& config)
{
    using namespace std::literals::chrono_literals;
    auto configuration = config.makeMdsConfiguration();
    return mds::Mds{configuration.setTimeout(1min)};
}

pgpool3::Pool& Globals::pool()
{
    return instance().poolHolder_.pool();
}

mds::Mds& Globals::mdsClient()
{
    return instance().mdsClient_;
}

mrc::signal_queue::ResultsQueue& Globals::resultsQueue()
{
    return instance().resultsQueue_;
}

const road_graph::Graph& Globals::roadGraph()
{
    return instance().roadGraph_;
}

const succinct_rtree::Rtree& Globals::roadGraphRTree()
{
    return instance().roadGraphRTree_;
}

const fb::GraphReader& Globals::graphCoverage()
{
    return instance().graphCoverage_;
}

const NGeobase::TLookup& Globals::geobaseLookup()
{
    return instance().geobaseLookup_;
}

ugc_event_logger::Logger& Globals::ugcEventLogger()
{
    return instance().ugcEventLogger_;
}

IWikiEditorClient& Globals::wikiEditorClient()
{
    return instance().wikiEditorClient_;
}

const ISuncalc& Globals::suncalc()
{
    return *instance().suncalcPtr_;
}

} // namespace maps::mrc::agent_proxy
