#include "operator.h"

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

#include <algorithm>

namespace maps::wiki::masstransit {

namespace {

const std::string MTR_YEAR_START_DATE = "0101";
const std::string MTR_YEAR_END_DATE = "1231";
const std::string MTR_DEFAULT_TIME = "0000";

common::Schedule
readOperatorSchedule(const pqxx::row& tuple)
{
    auto startTime = getAttr<std::string>(tuple, attr::TIME_START, MTR_DEFAULT_TIME);
    auto endTime = getAttr<std::string>(tuple, attr::TIME_END, MTR_DEFAULT_TIME);
    auto frequency = getAttr<int>(tuple, attr::FREQ, 0) * common::SECONDS_PER_MINUTE;

    return common::Schedule(
        MTR_YEAR_START_DATE, MTR_YEAR_END_DATE, common::WeekdayFlags::All,
        startTime, endTime, frequency);
}

} // namespace

Operator::Operator(const common::Schedule& schedule_)
    : schedule(schedule_)
{ }

YmapsdfOperatorHandler::YmapsdfOperatorHandler(Masstransit& masstransit)
    : YmapsdfObjectHandler(masstransit, masstransit.operators)
{ }

std::vector<FtType>
YmapsdfOperatorHandler::ftTypes() const
{
    return {FtType::TransportSystem};
}

std::string
YmapsdfOperatorHandler::loadRowsSqlTemplate() const
{
    std::ostringstream query;
    query << "SELECT ft.ft_id AS id"
          << ", ST_AsText(shape) AS shape";

    for (const auto& attr : {attr::TIME_START, attr::TIME_END, attr::FREQ}) {
        query << ", (SELECT value FROM ft_attr"
                 " WHERE calendar_ft.ft_id = ft_attr.ft_id"
                 " AND ft_attr.key = '" << attr << "') AS " << attr;
    }

    query << " FROM ft"
          << " LEFT JOIN ft_center USING (ft_id)"
          << " LEFT JOIN node USING (node_id)"
          << " LEFT JOIN ft calendar_ft ON"
          << " (ft.ft_id = calendar_ft.p_ft_id AND calendar_ft.ft_type_id=2207)"
          << " WHERE ft.ft_id IN %1%;";

    return query.str();
}

void
YmapsdfOperatorHandler::addObject(const pqxx::row& tuple)
{
    auto schedule = readOperatorSchedule(tuple);

    auto transportOperator = std::make_shared<Operator>(schedule);
    DBID operatorId = getAttr<DBID>(tuple, ymapsdf::ID);
    transportOperator->operatorId = operatorId;
    transportOperator->point = getAttr<Point>(tuple, ymapsdf::SHAPE);

    insert(operatorId, transportOperator);
}

} // namespace maps::wiki::masstransit
