package ru.yandex.webmaster3.worker.url.checker3.fetchers;

import NUrlChecker.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import ru.yandex.webmaster3.core.codes.DownloadedHttpCodeGroup;
import ru.yandex.webmaster3.core.data.HttpResponsePart;
import ru.yandex.webmaster3.core.util.ZoraResponseDocumentUtil;
import ru.yandex.webmaster3.core.zora.data.response.ZoraUrlFetchResponse;
import ru.yandex.webmaster3.storage.url.checker3.data.UrlCheckDataBlock;
import ru.yandex.webmaster3.storage.url.checker3.data.blocks.ServerResponseData;
import ru.yandex.webmaster3.worker.url.checker3.AbstractUrlCheckDataBlockFetcher;
import ru.yandex.wmtools.common.error.InternalException;
import ru.yandex.webmaster3.core.util.http.YandexMimeType;
import ru.yandex.wmtools.common.util.http.YandexHttpStatus;

import java.io.IOException;
import java.util.Comparator;
import java.util.List;

/**
 * @author leonidrom
 */
@Slf4j
public abstract class AbstractServerResponseDataFetcher extends AbstractUrlCheckDataBlockFetcher<ServerResponseData> {
    private static final Comparator<ServerResponseData.ResourceInfo> RESOURCE_SORT_COMPARATOR =
            Comparator.comparingInt(ServerResponseData.ResourceInfo::getHttpCode).reversed().
                    thenComparing(ServerResponseData.ResourceInfo::getUrl);

    @NotNull
    protected HttpResponsePart processZoraUrlFetchResponse(ZoraUrlFetchResponse zoraUrlFetchResponse) {
        boolean isText = zoraUrlFetchResponse.getMimeType() == YandexMimeType.MIME_TEXT
                || zoraUrlFetchResponse.getMimeType() == YandexMimeType.MIME_HTML
                || zoraUrlFetchResponse.getMimeType() == YandexMimeType.MIME_XML;

        String responseBody = null;
        if (isText) {
            try {
                responseBody = StringUtils.truncate(ZoraResponseDocumentUtil.getResponseString(zoraUrlFetchResponse),
                        UrlCheckDataBlock.MAX_TEXT_LENGTH);
            } catch (IOException | InternalException e) {
                log.error("Unable to get response body", e);
            }
        }

        return HttpResponsePart.createFromZoraResponse(zoraUrlFetchResponse, responseBody);
    }

    // оставляем только ресурсы с плохими http кодами
    protected List<ServerResponseData.ResourceInfo> processResources(Response.TUrlCheckResponse.TFetchResult fetchResult) {
        return fetchResult.getResourcesList().stream()
                .filter(r -> isShowToUser(r.getHttpCode()))
                .map(r -> new ServerResponseData.ResourceInfo(r.getUrl(), r.getHttpCode(), YandexMimeType.R.fromValueOrNull(r.getMimeType())))
                .distinct()
                .sorted(RESOURCE_SORT_COMPARATOR)
                .toList();
    }

    private static boolean isShowToUser(int httpCode) {
        // Ротор знал про этот ресурс, но его не скачивал
        if (httpCode == 0) {
            return false;
        }

        var grp = DownloadedHttpCodeGroup.get(httpCode).orElse(null);
        if (grp == null) {
            return false;
        }

        return (grp == DownloadedHttpCodeGroup.DOWNLOADED_4XX || grp == DownloadedHttpCodeGroup.DOWNLOADED_5XX);
    }
}
