#include "common.h"

namespace maps::wiki::masstransit {

namespace {

const std::map<MtrType, std::string> mtrTypeToString {
    {MtrType::Stop, "stop"},
    {MtrType::Route, "route"},
    {MtrType::Thread, "thread"},
    {MtrType::ThreadStop, "thread_stop"},
    {MtrType::Transition, "transition"},
    {MtrType::Schedule, "schedule"},
    {MtrType::TravelTime, "travel_time"},
    {MtrType::RouteAlias, "alias"}
};

const std::map<FtType, std::string> ftTypeToString {
    {FtType::TransportBusRoute, "bus"},
    {FtType::TransportTrolleybusRoute, "trolleybus"},
    {FtType::TransportTramRoute, "tramway"},
    {FtType::TransportMinibusRoute, "minibus"},
    {FtType::TransportMetroLine, "underground"},
    {FtType::TransportWaterwayRoute, "water"},
    {FtType::TransportMetroCableLine, "cable"},
    {FtType::TransportMetroTramLine, "rapid_tram"},
    {FtType::TransportMetroMonorailLine, "underground"},
    {FtType::TransportMetroBusLine, "metrobus"},
    {FtType::TransportMetroFunicularLine, "funicular"},

    {FtType::TransportBusStop, "stop"},
    {FtType::TransportWaterwayWharf, "stop"},
    {FtType::TransportWaterwaySeaport, "stop"},
    {FtType::TransportWaterwayRiverport, "stop"},
    {FtType::TransportMetroStation, "station"},
    {FtType::TransportMetroExit, "exit"}
};

} // namespace

MtrType
mtrType(FtType ftType)
{
    switch (ftType) {
        case FtType::TransportBusStop:
        case FtType::TransportMetroStation:
        case FtType::TransportMetroExit:
        case FtType::TransportWaterwayWharf:
        case FtType::TransportWaterwaySeaport:
        case FtType::TransportWaterwayRiverport:
            return MtrType::Stop;

        case FtType::TransportBusRoute:
        case FtType::TransportTrolleybusRoute:
        case FtType::TransportTramRoute:
        case FtType::TransportMinibusRoute:
        case FtType::TransportMetroLine:
        case FtType::TransportWaterwayRoute:
        case FtType::TransportMetroCableLine:
        case FtType::TransportMetroTramLine:
        case FtType::TransportMetroBusLine:
        case FtType::TransportMetroFunicularLine:
            return MtrType::Route;

        case FtType::TransportBusThread:
        case FtType::TransportTramThread:
        case FtType::TransportWaterwayThread:
        case FtType::TransportMetroThread:
            return MtrType::Thread;

        case FtType::TransportThreadStop:
            return MtrType::ThreadStop;

        case FtType::TransportMetroTransition:
        case FtType::TransportMetroPassageway:
            return MtrType::Transition;

        case FtType::TransportRouteAlias:
            return MtrType::RouteAlias;

        default: throw maps::RuntimeError() << "unknown ft_type: "
            << static_cast<typename std::underlying_type<FtType>::type>(ftType);
    }
}

std::string
toString(MtrType mtrType)
{
    const auto it = mtrTypeToString.find(mtrType);
    REQUIRE(it != mtrTypeToString.end(), "unsupported object type: "
        << static_cast<typename std::underlying_type<MtrType>::type>(mtrType));
    return it->second;
}

std::string
toString(FtType ftType)
{
    const auto it = ftTypeToString.find(ftType);
    REQUIRE(it != ftTypeToString.end(), "unsupported FtType: "
        << static_cast<typename std::underlying_type<FtType>::type>(ftType));
    return it->second;
}

common::ConditionType
toConditionType(DBID condTypeId)
{
    switch (condTypeId) {
        case 1:
            return common::ConditionType::Prohibited;
        case 3:
            return common::ConditionType::Uturn;
        default:
            throw maps::RuntimeError() << "unsupported condition type " << condTypeId;
    }
}

} // namespace maps::wiki::masstransit
