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

namespace maps::wiki::traffic_analyzer {

OnewayHypothesisGenerator::OnewayHypothesisGenerator(
        const IGraph& graph,
        PersIdToTracks persToTracks,
        const OnewayGenParams& params) :
    graph_(graph),
    persToTracks_(std::move(persToTracks)),
    params_(params)
{
}

std::vector<OnewayHypothesisGraph>
OnewayHypothesisGenerator::generate(
    const std::vector<TwoWayRoadIds>& twoWayRoads)
{
    uint32_t avWindow = persToTracks_.signalsPeriod().length().days();

    std::vector<OnewayHypothesisGraph> hypos;

    for (const auto& roadIds : twoWayRoads) {
        if (graph_.roadInfo(roadIds.fwd).funClass > params_.maxFunclass()) {
            continue;
        }

        uint32_t totalMatchedTracks = persToTracks_.tracksNum(roadIds.fwdPers) +
                                      persToTracks_.tracksNum(roadIds.bkwdPers);
        if (totalMatchedTracks < avWindow * params_.minBothEdgeTracks()) {
            continue;
        }

        double fwdMatchedRatio =
            1. * persToTracks_.tracksNum(roadIds.fwdPers) / totalMatchedTracks;
        double bkwdMatchedRatio =
            1. * persToTracks_.tracksNum(roadIds.bkwdPers) / totalMatchedTracks;

        if (fwdMatchedRatio >= params_.alarmMatchRatio()) {
            hypos.push_back({
                roadIds.fwd,
                RoadTraffic{
                    totalMatchedTracks,
                    fwdMatchedRatio,
                    graph_.version(),
                    persToTracks_.signalsPeriod()
                }
            });
        } else if (bkwdMatchedRatio >= params_.alarmMatchRatio()) {
            hypos.push_back({
                roadIds.bkwd,
                RoadTraffic{
                    totalMatchedTracks,
                    bkwdMatchedRatio,
                    graph_.version(),
                    persToTracks_.signalsPeriod()
                }
            });
        }
    }

    return hypos;
}

} // namespace maps::wiki::traffic_analyzer
