#include "categories.h"
#include "categories_strings.h"
#include "config.h"

#include <yandex/maps/wiki/configs/editor/categories.h>

#include <maps/libs/tile/include/utils.h>

namespace maps {
namespace wiki {

System::System(const maps::xml3::Node& node)
    : virtualWindow_(node.node("virtual-window"))
    , antiMeridianOverlapThreshold_(10.0)
    , antiMeridianGravityAccuracy_(10)
    , slavesPerRoleLimit_(node.node("xml-output").node("slaves-per-role").attr<size_t>("limit"))
    , revertObjectsLimit_(node.node("commits-revert").node("objects-without-role").attr<size_t>("limit"))
    , resolveResolutionCalcLimits_{
        std::chrono::milliseconds{node.node("resolve-resolution-calculation").attr<size_t>("timeout-ms")},
        node.node("resolve-resolution-calculation").attr<size_t>("commits-limit")}
{
}

double
System::antiMeridianGravityRadius(TZoom zoom) const
{
    double radius = antiMeridianGravityAccuracy_ *
        tile::zoomToResolution(zoom);
    return std::min(radius, antiMeridianOverlapThreshold_);
}

std::string
plainCategoryIdToCanonical(const std::string& plainCategoryId)
{
    return "cat:" + plainCategoryId;
}

StringSet
plainCategoryIdsToCanonical(const StringSet& plainCategoryIds)
{
    StringSet canonicalCategoryIds;
    for (const auto& catId : plainCategoryIds) {
        canonicalCategoryIds.insert(plainCategoryIdToCanonical(catId));
    }
    return canonicalCategoryIds;
}

std::string
canonicalCategoryIdToPlain(const std::string& canonicalCategoryId)
{
    if (canonicalCategoryId.find(RELATION_PREFIX) == 0) {
        return CATEGORY_RELATION;
    }
    if (canonicalCategoryId.find(CATEGORY_PREFIX) != 0) {
        return {};
    }
    return canonicalCategoryId.substr(CATEGORY_PREFIX.length());
}

StringSet
removeUndefinedCategories(StringSet&& original)
{
    const auto& categories = cfg()->editor()->categories();
    for (auto it = original.begin(); it != original.end();) {
        if (categories.defined(*it)) {
            ++it;
        } else {
            it = original.erase(it);
        }
    }
    return std::move(original);
}

} // namespace wiki
} // namespace maps
