package ru.yandex.webmaster3.worker.delurl;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.delurl.DelUrlRequest;
import ru.yandex.webmaster3.core.delurl.ProcessDelurlRequestTaskData;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.delurl.DelUrlRequestsService;
import ru.yandex.webmaster3.storage.delurl.DelUrlService;
import ru.yandex.webmaster3.worker.Task;

/**
 * Created by Oleg Bazdyrev on 09/10/2017.
 */
@Component
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Slf4j
public class ProcessDelurlRequestTask extends Task<ProcessDelurlRequestTaskData> {
    private final DelUrlService delurlService;
    private final DelUrlRequestsService delurlRequestsService;

    @Override
    public Result run(ProcessDelurlRequestTaskData data) throws Exception {
        var reqs = data.getRequests();
        List<DelUrlRequest> res = new ArrayList<>();
        if (reqs.size() == 1) {
            var req = reqs.get(0);
            log.info("DelUrlRequest: {},", req);
            res.add(delurlService.processUrl(req));
        } else if (reqs.size() > 1) {
            res = runAsync(reqs);
        }

        delurlRequestsService.updateBatch(res);
        return new Result(TaskResult.SUCCESS);
    }

    private List<DelUrlRequest> runAsync(List<DelUrlRequest> reqs) {
        List<Pair<DelUrlRequest, Future<DelUrlRequest>>> processedRequests = new ArrayList<>();
        for (DelUrlRequest r : reqs) {
            log.info("DelUrlRequest: {},", r);
            processedRequests.add(Pair.of(r, delurlService.processUrlAsync(r)));
        }

        return processedRequests.stream().map(p -> {
            try {
                return p.getValue().get();
            } catch (Exception e) {
                log.error("Error processing request " + p.getKey(), e);
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    @Override
    public Class<ProcessDelurlRequestTaskData> getDataClass() {
        return ProcessDelurlRequestTaskData.class;
    }
}
