package ru.yandex.webmaster3.viewer.http.url.checker3;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.yandex.autodoc.common.doc.annotation.Description;
import ru.yandex.webmaster3.core.http.ReadAction;
import ru.yandex.webmaster3.core.metrics.Category;
import ru.yandex.webmaster3.core.url.checker3.UrlCheckRequestParams;
import ru.yandex.webmaster3.core.util.IdUtils;
import ru.yandex.webmaster3.core.util.json.JsonMapping;
import ru.yandex.webmaster3.storage.crawl.service.CrawlSettingsService;
import ru.yandex.webmaster3.storage.url.checker3.dao.UrlCheckDataBlocksYDao;
import ru.yandex.webmaster3.storage.url.checker3.dao.UrlCheckRequests2YDao;
import ru.yandex.webmaster3.storage.url.checker3.data.UrlCheckDataBlock;
import ru.yandex.webmaster3.storage.url.checker3.data.UrlCheckDataBlockState;
import ru.yandex.webmaster3.storage.url.checker3.data.UrlCheckDataBlockType;
import ru.yandex.webmaster3.storage.url.checker3.data.blocks.UrlCheckRequestParamsData;
import ru.yandex.webmaster3.viewer.http.BaseWebmaster3Action;
import ru.yandex.webmaster3.viewer.http.async.model.AsyncInfoRequest;

import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author leonidrom
 */
@Description("Получить результат проверки урла")
@ReadAction
@Category("crawl")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Component("/urlchecker3/info")
public class GetUrlCheckInfoAction extends BaseWebmaster3Action<AsyncInfoRequest, GetUrlCheckInfoResponse> {
    private final UrlCheckDataBlocksYDao urlCheckDataBlocksYDao;
    private final UrlCheckRequests2YDao urlCheckRequests2YDao;
    private final CrawlSettingsService crawlSettingsService;

    @Override
    public GetUrlCheckInfoResponse process(AsyncInfoRequest request) {
        var dataBlocks = urlCheckDataBlocksYDao.get(request.getRequestId());
        if (dataBlocks.isEmpty()) {
            return new GetUrlCheckInfoResponse.RequestIdNotFoundResponse();
        }

        Map<UrlCheckDataBlockType, UrlCheckDataBlock> dataBlocksMap = dataBlocks.stream()
                .collect(Collectors.toMap(UrlCheckDataBlock::getBlockType, b -> b));

        if (UrlCheckDataBlock.anyOfState(dataBlocks, UrlCheckDataBlockState.INTERNAL_ERROR)) {
            return new GetUrlCheckInfoResponse.InternalErrorResponse();
        }

        if (UrlCheckDataBlock.anyOfState(dataBlocks, UrlCheckDataBlockState.ROBOT_FETCH_ERROR)) {
            return new GetUrlCheckInfoResponse.UnableToDownloadContentResponse();
        }

        if (UrlCheckDataBlock.anyOfState(dataBlocks, UrlCheckDataBlockState.TIMED_OUT)) {
            return new GetUrlCheckInfoResponse.TimedOutResponse();
        }

        if (UrlCheckDataBlock.anyOfState(dataBlocks, UrlCheckDataBlockState.IN_PROGRESS)) {
            return new GetUrlCheckInfoNormalResponse();
        }

        var urlCheckRequestParamsData = JsonMapping.readValue(
                dataBlocksMap.get(UrlCheckDataBlockType.URL_CHECK_REQUEST_PARAMS).getData(),
                UrlCheckRequestParamsData.class);
        UrlCheckRequestParams urlCheckRequestParams = urlCheckRequestParamsData.getUrlCheckRequestParams();

        UrlCheckDataBlock rotorCheckDataBlock;
        UrlCheckDataBlock pageDataBlock;
        UrlCheckDataBlock serverResponseDataBlock;
        if (dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_ROTOR_CHECK_RENDER_ON) != null) {
            rotorCheckDataBlock = dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_ROTOR_CHECK_RENDER_ON);
            pageDataBlock = dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_ARCHIVE_RENDER_ON);
            serverResponseDataBlock = dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_SERVER_RESPONSE_RENDER_ON);
        } else {
            rotorCheckDataBlock = dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_ROTOR_CHECK_RENDER_OFF);
            pageDataBlock = dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_ARCHIVE_RENDER_OFF);
            serverResponseDataBlock = dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_SERVER_RESPONSE_RENDER_OFF);
        }

        return GetUrlCheckInfoNormalResponse.fromDataBlocks(
                urlCheckRequestParams.getUrl(),
                crawlSettingsService.getRotorSettings(IdUtils.urlToHostId(urlCheckRequestParams.getUrl())).renderSettings(),
                dataBlocksMap.get(UrlCheckDataBlockType.SEARCH_INFO),
                dataBlocksMap.get(UrlCheckDataBlockType.ROBOT_INDEXING_INFO),
                dataBlocksMap.get(UrlCheckDataBlockType.TEXT_CONTENT),
                dataBlocksMap.get(UrlCheckDataBlockType.SEARCH_BASE_DATE),
                dataBlocksMap.get(UrlCheckDataBlockType.ROTOR_RENDER_SETTINGS),
                rotorCheckDataBlock,
                pageDataBlock,
                serverResponseDataBlock
        );
    }
}
