#include "ft_type.h"

#include <maps/libs/common/include/exception.h>

#include <map>
#include <vector>

namespace maps {
namespace wiki {
namespace importer {

using FtType = ymapsdf::ft::Type;

namespace {

/**
Only categories with point geomety
*/
const std::map<std::string, std::vector<FtType>> CATEGORY_TO_FT_TYPE {
    {"hydro_point", {
        FtType::HydroSpring,
        FtType::HydroFountain,
        FtType::HydroWaterfall,
        FtType::HydroWell,
        FtType::HydroGeyser,
        FtType::HydroStandpipe
    }},
    {"relief_point", {
        FtType::ReliefMountain,
        FtType::ReliefPass,
        FtType::ReliefVolcano
    }},
    {"urban_areal", {
        FtType::UrbanResidential,
        FtType::UrbanIndustrial,
        FtType::UrbanPublic,
        FtType::UrbanUnderConstruction,
        FtType::UrbanLeisure,
        FtType::UrbanReligionWorship,
        FtType::UrbanMedHospital,
        FtType::UrbanShopping,
        FtType::UrbanSport,
        FtType::UrbanSportground,
        FtType::UrbanTransport,
        FtType::UrbanLeisureBeach,
        FtType::UrbanGarbage,
        FtType::UrbanGov,
        FtType::UrbanEdu,
        FtType::UrbanBusinessCenter,
        FtType::UrbanPlayground,
        FtType::UrbanDogrun
    }},
    {"urban_roadnet_parking_lot", {
        FtType::UrbanRoadnetParkingLot,
        FtType::UrbanRoadnetParkingFree,
        FtType::UrbanRoadnetParkingToll,
        FtType::UrbanRoadnetParkingRestricted,
    }},
    {"transport_metro_station", {
        FtType::TransportMetroStation
    }},
    {"transport_metro_exit", {
        FtType::TransportMetroExit
    }},
    {"transport_railway_station", {
        FtType::TransportRailwayStation,
        FtType::TransportRailwayGoodsStation,
        FtType::TransportRailwayTerminal,
    }},
    {"transport_waterway_stop", {
        FtType::TransportWaterwayWharf,
        FtType::TransportWaterwaySeaport,
        FtType::TransportWaterwayRiverport
    }},
    {"transport_airport", {
        FtType::TransportAirport,
        FtType::TransportAirportDomestic,
        FtType::TransportAirportAirfield
    }},
    {"transport_helicopter", {
        FtType::TransportHelicopter
    }},
    {"transport_airport_terminal", {
        FtType::TransportAirportTerminal
    }},
    {"transport_terminal", {
        FtType::TransportBusTerminal
    }},
    {"transport_stop", {
        FtType::TransportTramStop,
        FtType::TransportBusStop,
        FtType::TransportTaxiStop,
        // +691
    }},
    {"poi_medicine", {
        FtType::UrbanMed,
        FtType::UrbanMedHospital,
        FtType::UrbanMedDental,
        FtType::UrbanMedVeterinary,
        FtType::UrbanMedPharmacy,
        FtType::UrbanMedOptician
    }},
    {"poi_edu", {
        FtType::UrbanEduKindergarten,
        FtType::UrbanEduSchoolSecondary,
        FtType::UrbanEduVocational,
        FtType::UrbanEduUniversity,
        FtType::UrbanEduExtraAcademic,
        FtType::UrbanEduLibrary,
        FtType::UrbanEduScientific
    }},
    {"poi_goverment", {
        FtType::UrbanGov,
        FtType::UrbanGovGovernment,
        FtType::UrbanGovCourt,
        FtType::UrbanGovPolice,
        FtType::UrbanGovFirefighting,
        FtType::UrbanGovCivilRegistry,
        FtType::UrbanGovMigration,
        FtType::UrbanGovCenter,
        FtType::UrbanGovSocialSecurity,
        FtType::UrbanGovTaxInspectorate,
        FtType::UrbanGovRecruitmentCenter,
        FtType::UrbanGovPrison,
        FtType::UrbanGovCondoManagement,
        FtType::UrbanGovPost,
        FtType::UrbanGovEmbassy
    }},
    {"poi_religion", {
        FtType::UrbanReligionWorship,
        FtType::UrbanReligionChrist,
        FtType::UrbanReligionIslam,
        FtType::UrbanReligionJudaism,
        FtType::UrbanReligionBuddhism
    }},
    {"poi_food", {
        FtType::UrbanFoodservice,
        FtType::UrbanFoodserviceFastfood,
        FtType::UrbanFoodserviceBar,
        FtType::UrbanFoodserviceRestaurant,
        FtType::UrbanFoodserviceCoffeeShop
    }},
    {"poi_shopping", {
        FtType::UrbanShopping,
        FtType::UrbanShoppingMall,
        FtType::UrbanShoppingStall,
        FtType::UrbanShoppingMarketFarmers,
        FtType::UrbanShoppingMarketClothes,
        FtType::UrbanShoppingMarketHousehold,
        FtType::UrbanShoppingGrocery,
        FtType::UrbanShoppingFlowers,
        FtType::UrbanShoppingBook,
        FtType::UrbanShoppingAntiques,
        FtType::UrbanShoppingHousehold,
        FtType::UrbanShoppingAppliances,
        FtType::UrbanShoppingSport,
        FtType::UrbanShoppingPerfumery,
        FtType::UrbanShoppingFurniture,
        FtType::UrbanShoppingFashion,
        FtType::UrbanShoppingTextile,
        FtType::UrbanShoppingPet,
        FtType::UrbanShoppingToy,
        FtType::UrbanShoppingJewelry,
        FtType::UrbanShoppingSouvenirs,
        FtType::UrbanShoppingDelivery
    }},
    {"poi_auto", {
        FtType::UrbanCar,
        FtType::UrbanCarFuelStation,
        FtType::UrbanCarTrafficPolice,
        FtType::UrbanCarDealership,
        FtType::UrbanCarParts,
        FtType::UrbanCarRepairshop,
        FtType::UrbanCarTyreshop,
        FtType::UrbanCarCarwash,
        FtType::UrbanCarGarage,
        FtType::UrbanCarDrivingSchool,
        FtType::UrbanCarImpoundLot,
        FtType::UrbanCarTrainingFacility,
        FtType::UrbanCarInspectionStation
    }},
    {"poi_finance", {
        FtType::UrbanMoney,
        FtType::UrbanMoneyBank,
        FtType::UrbanMoneyPawnshop,
        FtType::UrbanMoneyAtm,
        FtType::UrbanMoneyCurrencyExchange,
        FtType::UrbanMoneyPaymentMachine,
        FtType::UrbanMoneyInsurance,
        FtType::UrbanMoneyMicrofinance
    }},
    {"poi_service", {
        FtType::UrbanService,
        FtType::UrbanServiceFactory,
        FtType::UrbanServiceNotary,
        FtType::UrbanServiceLawyer,
        FtType::UrbanServiceBarbershop,
        FtType::UrbanServiceLaundry,
        FtType::UrbanServiceRepair,
        FtType::UrbanServicePhoto,
        FtType::UrbanServicePhoneshop,
        FtType::UrbanServiceTravelAgency,
        FtType::UrbanServiceTicketTransport,
        FtType::UrbanServiceSauna,
        FtType::UrbanServiceFuneral,
        FtType::UrbanServiceRealty,
        FtType::UrbanServiceWasteDisposal,
        FtType::UrbanServiceToilet,
        FtType::UrbanServiceNonprofit,
        FtType::UrbanBusinessCenter
    }},
    {"poi_sport", {
        FtType::UrbanSport,
        FtType::UrbanSportStadium,
        FtType::UrbanSportClub,
        FtType::UrbanSportSwimmingPool,
        FtType::UrbanSportSki,
        FtType::UrbanSportHippodrome,
        FtType::UrbanSportRacetrack
    }},
    {"poi_leisure", {
        FtType::UrbanLeisure,
        FtType::UrbanLeisureHotel,
        FtType::UrbanLeisureBeach,
        FtType::UrbanLeisureSanatorium,
        FtType::UrbanLeisureKidscamp,
        FtType::UrbanLeisureAnimalpark,
        FtType::UrbanLeisureTheater,
        FtType::UrbanLeisureConcertHall,
        FtType::UrbanLeisureCircus,
        FtType::UrbanLeisureCinema,
        FtType::UrbanLeisureMuseum,
        FtType::UrbanLeisureAmusementpark,
        FtType::UrbanLeisureEntertainmentCenter,
        FtType::UrbanLeisureWaterpark,
        FtType::UrbanLeisureHouseOfCulture,
        FtType::UrbanLeisureNightClub,
        FtType::UrbanLeisureObservationDeck,
        FtType::UrbanLeisureMonument,
        FtType::Landmark
    }},
    {"poi_urban", {
        FtType::UrbanPlayground,
        FtType::UrbanSportground,
        FtType::UrbanDogrun,
        FtType::UrbanGarbage,
        FtType::UrbanBikeRental,
        FtType::UrbanLandmarkMinor,
        FtType::UrbanBikeParkingLot
    }}
};

struct CategoryMapper
{
    CategoryMapper()
    {
        for (const auto& kv : CATEGORY_TO_FT_TYPE) {
            const auto& category = kv.first;
            const auto& ftvec = kv.second;

            for (const auto& ft : ftvec) {
                ftTypeToCategory.emplace(ft, category);
            }
        }
    }

    std::map<FtType, std::string> ftTypeToCategory;
};

CategoryMapper MAPPER;

} // namespace

std::string ftTypeToCategory(FtType ftType)
{
    auto it = MAPPER.ftTypeToCategory.find(ftType);
    REQUIRE(it != MAPPER.ftTypeToCategory.end(), "There is no category for ft type " << static_cast<int>(ftType));
    return it->second;
}

} // namespace importer
} // namespace wiki
} // namespace maps
