#include <maps/wikimap/mapspro/services/mrc/long_tasks/toloka_manager_cron_jobs/lib/include/taxonomy.h>

namespace maps {
namespace mrc {
namespace toloka {

Taxonomy::TaskOutput Taxonomy::mergeSingleTaskResults(
    const Taxonomy::AssignmentResults& results,
    size_t taskIdx,
    Taxonomy::UserIdToStat& userIdToStat)
{
    std::vector<Taxonomy::TaskOutput> outputs;
    for (const auto& res : results) {
        outputs.push_back(res.outputs[taskIdx]);
    }

    std::sort(outputs.begin(), outputs.end());
    const auto pair = longestEqualRange(outputs.begin(), outputs.end());
    if ((size_t)std::distance(pair.first, pair.second)
        <= outputs.size() / 2) {
        return Taxonomy::TaskOutput{""};
    }
    Taxonomy::TaskOutput majorityOutput = *pair.first;

    for (const auto& res : results) {
        if (!userIdToStat.count(res.userId)) {
            userIdToStat.emplace(res.userId, Taxonomy::UserStat(res));
        }
        auto& stat = userIdToStat.at(res.userId);
        const auto& userOutput = res.outputs[taskIdx];
        if (userOutput == majorityOutput) {
            ++stat.correctCount;
        }
    }
    return majorityOutput;
}

Taxonomy::TaskSuiteResult Taxonomy::mergeTaskSuiteResults(
    const Taxonomy::AssignmentResults& assignmentResults)
{
    return mergeTaskSuiteResultsImpl<Taxonomy>(assignmentResults);
}


void Taxonomy::evaluateAssignments(
    const io::TolokaClient& tolokaClient,
    const Taxonomy::TaskSuiteResult& tsResult)
{
    evaluateAssignmentsImpl<Taxonomy>(tolokaClient, tsResult);
}

} // toloka
} // mrc
} // maps
