package ru.yandex.webmaster3.viewer.http.links;

import java.util.*;
import java.util.stream.Collectors;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;

import ru.yandex.webmaster3.core.codes.ErrorGroupEnum;
import ru.yandex.webmaster3.core.codes.LinkType;
import ru.yandex.webmaster3.core.data.HttpCodeInfo;
import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.storage.links.LinksService;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostAction;

/**
 * @author aherman
 */
@ReadAction
@Category("links")
public class GetInternalLinkBrokenHistoryAction
        extends AbstractUserVerifiedHostAction<GetInternalLinkBrokenHistoryRequest, GetInternalLinkBrokenHistoryResponse>
{
    private static final Logger log = LoggerFactory.getLogger(GetInternalLinkBrokenHistoryAction.class);

    private LinksService linksService;

    @Override
    public GetInternalLinkBrokenHistoryResponse process(GetInternalLinkBrokenHistoryRequest request) {
        var hostId = request.getHostId();
        var dateFrom = request.getDateFrom();
        var dateTo = request.getDateTo();

        Map<HttpCodeInfo, NavigableMap<LocalDate, Long>> httpCodeHistory = linksService.getInternalHttpHistory(
                hostId,
                dateFrom, dateTo,
                LinksService.INTERNAL_LINKS_BROKEN_HISTORY_PREDICATE
        );

        Map<ErrorGroupEnum, NavigableMap<LocalDate, Long>> result = new EnumMap<>(ErrorGroupEnum.class);
        httpCodeHistory.forEach((key, value) -> {
            // наличие значения в ErrorGroupEnum гарантируется предикатом выше
            ErrorGroupEnum errorGroupEnum = ErrorGroupEnum.get(key.getCode()).get();
            NavigableMap<LocalDate, Long> groupHistory =
                    result.computeIfAbsent(errorGroupEnum, g -> new TreeMap<>());
            groupHistory = HistoryUtil.merge(groupHistory, value);
            result.put(errorGroupEnum, groupHistory);
        });

        List<GetInternalLinkBrokenHistoryResponse.BrokenGroupHistory> r = result.entrySet().stream()
                .map(entry -> new GetInternalLinkBrokenHistoryResponse.BrokenGroupHistory(
                        LinkIndicator.fromGroup(entry.getKey()),
                        HistoryUtil.toDataPoint(entry.getValue())))
                .collect(Collectors.toList());

        return new GetInternalLinkBrokenHistoryResponse.NormalResponse(r);
    }

    @Required
    public void setLinksService(LinksService linksService) {
        this.linksService = linksService;
    }
}
