package ru.yandex.webmaster3.worker.robotstxt;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.robotstxt.AnalyzeRobotTxtTaskData;
import ru.yandex.webmaster3.storage.async.AsyncRequestTaskService;
import ru.yandex.webmaster3.storage.async.model.HttpAsyncRequestInfoResultType;
import ru.yandex.webmaster3.storage.robotstxt.AnalyzeRobotsTxtService;
import ru.yandex.webmaster3.storage.robotstxt.exception.AnalisisRobotsTxtException;
import ru.yandex.webmaster3.storage.robotstxt.exception.AnalisisRobotsTxtHttpResponseException;
import ru.yandex.webmaster3.storage.robotstxt.model.AnalyzeRobotsTxtInputData;
import ru.yandex.webmaster3.storage.robotstxt.model.AnalyzeRobotsTxtResponseType;
import ru.yandex.webmaster3.storage.robotstxt.model.AnalyzeRobotsTxtResult;
import ru.yandex.webmaster3.storage.robotstxt.model.RobotsTxtErrorTransfer;
import ru.yandex.webmaster3.worker.Task;
import ru.yandex.webmaster3.worker.queue.TaskQueueMetrics;

/**
 * @author: ishalaru
 * DATE: 20.05.2019
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class RobotsTxtAnalysisTask extends Task<AnalyzeRobotTxtTaskData> {
    private static final int MAX_CONCURRENT_TASKS = 32;

    private final AnalyzeRobotsTxtService analyzeRobotsTxtService;
    private final AsyncRequestTaskService asyncRequestTaskService;

    @Override
    public Result run(AnalyzeRobotTxtTaskData data) throws Exception {
        asyncRequestTaskService.startWorkingTask(data.getRequestId());
        try {
            AnalyzeRobotsTxtInputData analyzeRobotsTxtInputData = new AnalyzeRobotsTxtInputData(data.getRobotsTxtContent(), data.getHostName(), data.isLoadOnly(), data.getUrls());
            AnalyzeRobotsTxtResult result = analyzeRobotsTxtService.process(analyzeRobotsTxtInputData);
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), AnalyzeRobotsTxtResponseType.NORMAL.getValue(), result);
        } catch (AnalisisRobotsTxtHttpResponseException exp) {
            RobotsTxtErrorTransfer robotsTxtErrorTransfer = new RobotsTxtErrorTransfer(exp.getError(), exp.getHttpResponse());
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), AnalyzeRobotsTxtResponseType.HTTP_PROBLEM.getValue(), robotsTxtErrorTransfer);
        } catch (AnalisisRobotsTxtException exp) {
            asyncRequestTaskService.finishWorkingTask(data.getRequestId(), AnalyzeRobotsTxtResponseType.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<AnalyzeRobotTxtTaskData> getDataClass() {
        return AnalyzeRobotTxtTaskData.class;
    }


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

}
