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

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

using categories::RD_EL;
using categories::RD_JC;
using categories::COND_TRAFFIC_LIGHT;

VALIDATOR_CHECK_PART( traffic_lights, logic, COND_TRAFFIC_LIGHT, RD_JC, RD_EL )
{
    context->objects<COND_TRAFFIC_LIGHT>().visit(
            [&](const TrafficLight* trafficLight) {
        if (!context->objects<RD_JC>().loaded(
                trafficLight->placedAtJunction())) {
            // Traffic light out of AOI
            return;
        }

        for (TId elementId : trafficLight->controlledRoadElements()) {
            if (!context->objects<RD_EL>().loaded(elementId)) {
                continue;
            }
            auto controlledElement = context->objects<RD_EL>().byId(elementId);
            if (!canPassRoadElementFrom(
                    controlledElement,
                    utils::oppositeJunctionId(
                        controlledElement,
                        trafficLight->placedAtJunction()))) {
                context->error(
                    "unpassable-controlled-element",
                    utils::geomForReport(controlledElement),
                    { trafficLight->id(), elementId });
            }
        }
    });
}

VALIDATOR_CHECK_PART( traffic_lights, road_class, COND_TRAFFIC_LIGHT, RD_JC, RD_EL )
{
    context->objects<COND_TRAFFIC_LIGHT>().visit(
            [&](const TrafficLight* trafficLight) {
        for (const auto& elementId : trafficLight->controlledRoadElements()) {
            if (!context->objects<RD_EL>().loaded(elementId)) {
                continue;
            }
            const RoadElement* element = context->objects<RD_EL>().byId(elementId);
            const int elementFc = element->fc();
            if (elementFc == 1 || elementFc >= 9) {
                context->error(
                    "wrong-fc-traffic-light-controlled",
                    utils::geomForReport(element),
                    { trafficLight->id(), elementId });
            }
        }
    });
}


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