#include "stop.h"

#include <maps/wikimap/mapspro/libs/masstransit/masstransit.h>
#include "stop_closure.h"

#include <maps/libs/locale/include/codes.h>

namespace maps::wiki::masstransit {

Stop::Stop()
    : stopId(0)
    , parentStopId(0)
    , ftType(FtType::None)
    , point(0.0, 0.0)
    , isWaypoint(false)
{ }

YmapsdfStopHandler::YmapsdfStopHandler(Masstransit& masstransit)
    : YmapsdfObjectHandler(masstransit, masstransit.stops)
{ }

std::vector<FtType>
YmapsdfStopHandler::ftTypes() const
{
    return {
        FtType::TransportBusStop,
        FtType::TransportMetroStation,
        FtType::TransportMetroExit,
        FtType::TransportWaterwayWharf,
        FtType::TransportWaterwaySeaport,
        FtType::TransportWaterwayRiverport
    };
}

StringVector
YmapsdfStopHandler::attrs() const
{
    return {
        attr::CLOSURE,
        attr::WAYPOINT
    };
}

void
YmapsdfStopHandler::addObject(const pqxx::row& tuple)
{
    auto stop = std::make_shared<Stop>();
    stop->stopId = getAttr<DBID>(tuple, ymapsdf::ID);
    stop->name = getAttr<std::string>(tuple, ymapsdf::NAME, "");
    stop->point = getAttr<Point>(tuple, ymapsdf::SHAPE);
    stop->ftType = getAttr<FtType>(tuple, ymapsdf::FT_TYPE_ID);
    stop->isWaypoint = getAttr<bool>(tuple, attr::WAYPOINT);
    stop->parentStopId = stop->ftType == FtType::TransportMetroExit
        ? getAttr<DBID>(tuple, ymapsdf::P_FT_ID, 0)
        : 0;

    auto mtrId = getAttr<std::string>(tuple, ymapsdf::SOURCE_ID, std::to_string(stop->stopId));
    idMap().add(stop->stopId, mtrId, MtrType::Stop);
    insert(stop->stopId, stop);
    if (getAttr<bool>(tuple, attr::CLOSURE, false) && !stop->isWaypoint) {
        masstransit_.stopClosures.insert(stop->stopId,
            std::make_shared<StopClosure>(stop->stopId));
    }
}

MtrStopHandler::MtrStopHandler(Masstransit& masstransit)
    : MtrObjectHandler(masstransit, masstransit.stops)
{ }

void
MtrStopHandler::writeObject(StreamMap& ostreams, const Object& object)
{
    const auto& stop = dynamic_cast<const Stop&>(object);

    if (stop.isWaypoint) {
        return;
    }

    double latitude = stop.point.y();
    double longitude = stop.point.x();

    auto& ostream = ostreams[fileNames().front()];
    ostream << idMap().getMtrId(stop.stopId) << FIELD_SEPARATOR;
    if (stop.parentStopId != 0) {
        ostream << idMap().getMtrId(stop.parentStopId);
    }
    ostream << FIELD_SEPARATOR
        << stop.name << FIELD_SEPARATOR
        << toString(stop.ftType) << FIELD_SEPARATOR
        << latitude << FIELD_SEPARATOR
        << longitude << std::endl;
}

} // namespace maps::wiki::masstransit
