package ru.yandex.qe.hitman.comrade.script.execution.groovy.example

import ru.yandex.qe.hitman.comrade.script.model.ComradeClient
import ru.yandex.qe.hitman.comrade.script.model.EventListener
import ru.yandex.qe.hitman.comrade.script.model.Storage
import ru.yandex.qe.hitman.comrade.script.model.operation.IncrementTaskOverlapOperation
import ru.yandex.qe.hitman.comrade.script.model.toloka.Assignment
import ru.yandex.qe.hitman.comrade.script.model.toloka.AssignmentStatus
import ru.yandex.qe.hitman.comrade.script.model.toloka.IncrementOverlapParams
import ru.yandex.qe.hitman.comrade.script.util.Answer
import ru.yandex.qe.hitman.comrade.script.util.ComradeUtils
import ru.yandex.qe.hitman.comrade.script.util.collections.Counters

class DynamicOverlap2Plus1WithIncrementOperation implements EventListener {
    private boolean moreLogging

    @Override
    void onEvent(List<Assignment> events, ComradeClient client) {
        long start = System.currentTimeMillis();
        loadGlobals(client)

        events.groupBy { it.poolId }.each {poolId, eventsByPool ->

            def newAnswers = ComradeUtils.assignmentToAnswers(eventsByPool)
                    .findAll({ it.getStatus() == AssignmentStatus.ACCEPTED })
            client.logger.info("New answers size={}", newAnswers.size())

            def groupedNewAnswers = newAnswers.findAll({ !it.task.isHoneypot() && !it.task.isHint() }).groupBy { it.task }
            groupedNewAnswers.each { task, answers ->
                List<Answer> allAnswersForTask = ComradeUtils.saveNewAnswersAndLoadAll(answers, task, client.storage)

                if (allAnswersForTask.size() == 2) {
                    if (allAnswersForTask[0].solution != allAnswersForTask[1].solution) {
                        if (moreLogging) {
                            client.logger.info("Solutions are different for input {}: {} and {}", task.inputValues, allAnswersForTask[0].solution, allAnswersForTask[1].solution)
                        }
                        client.enqueueOperation(new IncrementTaskOverlapOperation(new IncrementOverlapParams(task.getTaskId(), 3)))
                    } else {
                        if (moreLogging) {
                            client.logger.info("Solutions are equal for input {}", task.inputValues)
                        }
                    }
                } else if (allAnswersForTask.size() <= 1) {
                    client.enqueueOperation(new IncrementTaskOverlapOperation(new IncrementOverlapParams(task.getTaskId(), 2)))
                    if (moreLogging) {
                        client.logger.info("One more time for {}", task.inputValues)
                    }
                } else {
                    if (moreLogging) {
                        client.logger.info("There are {} solutions for input {}", allAnswersForTask.size(), task.inputValues)
                    }
                }
            }
        }

        client.logger.info("Time: {}", System.currentTimeMillis() - start)
    }

    private void loadGlobals(ComradeClient client) {
        Storage storage = client.storage;
        def params = storage.get("params").orElseThrow({
            new RuntimeException("Init storage should contain params")
        })
        moreLogging = params.moreLogging != null && params.moreLogging
    }
}
