#include "module.h"
#include <yandex/maps/wiki/validator/check.h>
#include <yandex/maps/wiki/validator/categories.h>

#include "../utils/misc.h"

#if YANDEX_MAPS_UBUNTU_VERSION == 1004
// fix boost 1.40
#include "date_formatting_lucid.hpp"
#endif

#include <boost/date_time/gregorian/gregorian.hpp>
#include <stdexcept>

namespace maps {
namespace wiki {
namespace validator {
namespace checks {

using categories::RD_EL;

namespace {

const boost::gregorian::days CRITICAL_THRESHOLD{30};
const boost::gregorian::days WARNING_THRESHOLD{60};

} // namespace

VALIDATOR_SIMPLE_CHECK( uc_open_at, RD_EL )
{
    context->objects<RD_EL>().visit(
            [&](const RoadElement* element)
    {
        const auto& openAt = element->openAt();

        if (openAt.empty()) {
            return;
        }

        boost::gregorian::date openAtDate;
        try {
            if (openAt.size() != 8) {
                throw std::out_of_range("invalid date length");
            }
            openAtDate = boost::gregorian::from_undelimited_string(openAt);
        } catch (const std::exception&) {
            context->error("bad-open-at",
                utils::geomForReport(element), {element->id()});
            return;
        }

        if (!element->underConstruction()) {
            auto severity = openAtDate < boost::gregorian::date(2025, 1, 1)
                ? Severity::Error
                : Severity::Warning;
            context->report(severity, "uc-open-at-without-uc",
                utils::geomForReport(element), {element->id()});
        }

        auto currentDate = boost::gregorian::day_clock::universal_day();
        if (openAtDate <= currentDate) {
            context->error("open-at-in-past",
                utils::geomForReport(element), {element->id()});
        } else if (openAtDate - currentDate < CRITICAL_THRESHOLD) {
            context->error("open-at-soon",
                utils::geomForReport(element), {element->id()});
        } else if (openAtDate - currentDate < WARNING_THRESHOLD) {
            context->warning("open-at-soon",
                utils::geomForReport(element), {element->id()});
        }
    });
}

} // namespace checks
} // namespace validator
} // namespace wiki
} // namespace maps
