package ru.yandex.webmaster3.worker.http.abt;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.Action;
import ru.yandex.webmaster3.core.http.ActionRequest;
import ru.yandex.webmaster3.core.http.ActionResponse;
import ru.yandex.webmaster3.core.http.RequestQueryProperty;
import ru.yandex.webmaster3.core.http.WriteAction;
import ru.yandex.webmaster3.storage.abt.AbtService;
import ru.yandex.webmaster3.storage.abt.dao.AbtHostExperimentYDao;
import ru.yandex.webmaster3.storage.abt.dao.AbtUserExperimentYDao;
import ru.yandex.webmaster3.storage.abt.hash.AbtHashExperimentYDao;
import ru.yandex.webmaster3.storage.abt.model.SimpleExperiment;

/**
 * Чистит отсутствующие эксперименты (опционально и неакивные)
 */
@Slf4j
@WriteAction
@Component("/experiment/clean")
@AllArgsConstructor(onConstructor_ = @Autowired)
public class CleanExperimentsAction extends Action<CleanExperimentsAction.Request, ActionResponse> {

    private final AbtService abtService;
    private final AbtHostExperimentYDao abtHostExperimentYDao;
    private final AbtUserExperimentYDao abtUserExperimentYDao;
    private final AbtHashExperimentYDao abtHashExperimentYDao;

    @Override
    public ActionResponse process(Request request) throws WebmasterException {
        // соберем все поддерживаемые экспы
        Set<String> experiments = new HashSet<>();
        final Map<String, SimpleExperiment> simpleExperiments = abtService.listAllExperiments();
        for (var exp : simpleExperiments.values()) {
            if (!request.clearInactive || exp.isActive()) {
                experiments.add(exp.getName());
            }
        }
        abtHostExperimentYDao.forEach(pair -> {
            if (!experiments.contains(pair.getRight().getExperiment())) {
                log.info("Removing record with exp {} for host {}", pair.getRight().getExperiment(), pair.getLeft());
                abtHostExperimentYDao.delete(pair.getLeft(), pair.getRight());
            }
        });
        abtUserExperimentYDao.forEach(pair -> {
            if (!experiments.contains(pair.getRight().getExperiment())) {
                log.info("Removing record with exp {} for user {}", pair.getRight().getExperiment(), pair.getLeft());
                abtUserExperimentYDao.delete(pair.getLeft(), pair.getRight());
            }
        });
        abtHashExperimentYDao.getRecords().forEach(record -> {
            if (!experiments.contains(record.getExperiment())) {
                log.info("Removing hash exp {}", record.getExperiment());
                abtHashExperimentYDao.delete(record);
            }
        });

        return new ActionResponse.NormalResponse() {};
    }

    public static final class Request implements ActionRequest {
        private boolean clearInactive = false;

        @RequestQueryProperty
        public void setClearInactive(boolean clearInactive) {
            this.clearInactive = clearInactive;
        }
    }
}
