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

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Required;

import ru.yandex.webmaster3.core.codes.ErrorGroupEnum;
import ru.yandex.webmaster3.core.codes.HttpCodeGroup;
import ru.yandex.webmaster3.core.codes.LinkType;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.link.HostLinkSample;
import ru.yandex.webmaster3.core.util.PageUtils;
import ru.yandex.webmaster3.storage.links2.Link2SamplesService;
import ru.yandex.webmaster3.viewer.http.AbstractUserVerifiedHostAction;
import ru.yandex.wmtools.common.util.http.YandexHttpStatus;

/**
 * @author aherman
 */
@ReadAction
@Category("links")
public class GetInternalLinkBrokenSamplesAction
        extends AbstractUserVerifiedHostAction<GetInternalLinkBrokenSamplesRequest, LinkSamplesResponse>
{
    private Link2SamplesService link2SamplesService;

    @Override
    public LinkSamplesResponse process(GetInternalLinkBrokenSamplesRequest request) {
        Set<Integer> httpCodes = getHttpCodes(request.getIndicators());
        long totalSamples = link2SamplesService.countInternalSamples(request.getHostId(), httpCodes);

        PageUtils.LongPager page = PageUtils.getPage(request.getPage(), request.getPageSize(), totalSamples);
        if (page.isEmpty()) {
            return new LinkSamplesResponse.NormalResponse(Collections.emptyList(), totalSamples);
        }

        List<HostLinkSample> samples = link2SamplesService.listInternalSamples(
                request.getHostId(),
                httpCodes,
                page.toRangeStart(),
                page.getPageSize()
        );

        return new LinkSamplesResponse.NormalResponse(samples, totalSamples);
    }

    public Set<Integer> getHttpCodes(LinkIndicator.Broken[] indicators) {
        Set<ErrorGroupEnum> errorGroups = new HashSet<>();
        if (ArrayUtils.isEmpty(indicators)) {
            errorGroups.addAll(Arrays.asList(ErrorGroupEnum.values()));
        } else {
            for (LinkIndicator.Broken indicator : indicators) {
                errorGroups.add(LinkIndicator.toGroup(indicator));
            }
        }

        return errorGroups.stream()
                .flatMap(errorGroup -> errorGroup.getHttpCodes().stream())
                .collect(Collectors.toSet());
    }

    @Required
    public void setLink2SamplesService(Link2SamplesService link2SamplesService) {
        this.link2SamplesService = link2SamplesService;
    }
}
