package ru.yandex.webmaster3.worker.sitemap;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.core.worker.task.sitemap.SitemapAnalysisTaskData;
import ru.yandex.webmaster3.storage.async.model.HttpAsyncRequestInfoResultType;
import ru.yandex.webmaster3.storage.sitemap.service.AnalyzeSitemapActionService;
import ru.yandex.webmaster3.storage.async.AsyncRequestTaskService;
import ru.yandex.webmaster3.storage.sitemap.service.exception.AnalysisSitemapActionException;
import ru.yandex.webmaster3.storage.sitemap.service.exception.AnalysisSitemapIncorrectResponseException;
import ru.yandex.webmaster3.storage.sitemap.service.model.AnalyzeSitemapErrorTransfer;
import ru.yandex.webmaster3.storage.sitemap.service.model.AnalyzeSitemapInputData;
import ru.yandex.webmaster3.storage.sitemap.service.model.AnalyzeSitemapResponseType;
import ru.yandex.webmaster3.storage.sitemap.service.model.SitemapAnalysisExtendedResult;
import ru.yandex.webmaster3.worker.Task;
import ru.yandex.webmaster3.worker.queue.TaskQueueMetrics;

/**
 * @author: ishalaru
 * DATE: 15.05.2019
 * Task start Sitemap analysis
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class SitemapAnalysisTask extends Task<SitemapAnalysisTaskData> {
    private static final int MAX_CONCURRENT_TASKS = 32;

    private final AnalyzeSitemapActionService analyzeSitemapActionService;
    private final AsyncRequestTaskService asyncRequestTaskService;

    @Override
    public Result run(SitemapAnalysisTaskData data) throws Exception {
        asyncRequestTaskService.startWorkingTask(data.getRequestId());
        try {
            SitemapAnalysisExtendedResult result = analyzeSitemapActionService.process(new AnalyzeSitemapInputData(data.getSitemapText(), data.getSitemapUrl(), data.getSitemapFile()));
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), AnalyzeSitemapResponseType.NORMAL.getValue(), result);
        } catch (AnalysisSitemapIncorrectResponseException exp) {
            AnalyzeSitemapErrorTransfer analyzeSitemapErrorTransfer = new AnalyzeSitemapErrorTransfer(exp.getError(), exp.getHttpResponsePart());
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), AnalyzeSitemapResponseType.HTTP_PROBLEM.getValue(), analyzeSitemapErrorTransfer);
        } catch (AnalysisSitemapActionException exp) {
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), AnalyzeSitemapResponseType.COMMON_PROBLEM.getValue(), exp.getError());
        } catch (Exception exp) {
            log.error("SiteAnalysis task failed.", exp);
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), HttpAsyncRequestInfoResultType.INTERNAL_ERROR);
            return new Result(TaskResult.FAIL);
        }
        return new Result(TaskResult.SUCCESS);

    }

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

    @Override
    public float getPriority(TaskQueueMetrics.TaskStatistics stats) {
        if (stats.getProcessing() >= MAX_CONCURRENT_TASKS) {
            return 0;
        } else {
            return super.getPriority(stats);
        }
    }
}
