package ru.yandex.webmaster3.worker.mobile;

import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;

import ru.yandex.webmaster3.core.worker.task.MobileAuditForUrlTaskData;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.mobile.MobileAuditRequestsService;
import ru.yandex.webmaster3.storage.mobile.data.MobileAuditRequestInfo;
import ru.yandex.webmaster3.storage.mobile.data.MobileAuditResult;
import ru.yandex.webmaster3.worker.RpsLimitedTask;
import ru.yandex.webmaster3.worker.queue.TaskQueueMetrics;

/**
 * @author avhaliullin
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class MobileAuditForUrlTask extends RpsLimitedTask<MobileAuditForUrlTaskData> {
    private static final Logger log = LoggerFactory.getLogger(MobileAuditForUrlTask.class);
    private static final int MAX_CONCURRENT_TASKS = 32;

    private final MobileAuditRequestsService mobileAuditRequestsService;
    private final MobileAuditService mobileAuditService;
    private int queueSizeLimit;

    @Override
    public Result run(MobileAuditForUrlTaskData data) throws Exception {
        MobileAuditRequestInfo requestInfo =
                mobileAuditRequestsService.workerStartedTask(data.getUserId(), data.getHostId(), data.getTaskId());

        if (requestInfo != null) {
            MobileAuditResult resultGorotor;
            try {
                resultGorotor = mobileAuditService.checkUrl(requestInfo.getUrl(), requestInfo.getResolution());
                log.info("Gorotor Mobile audit result {}", resultGorotor.getType());
            } catch (Exception e) {
                log.error("Gorotor Mobile audit failed for host {}", data.getHostId(), e);
                mobileAuditRequestsService.finishTask(data.getHostId(), data.getTaskId(), new MobileAuditResult.InternalError());
                return new Result(TaskResult.FAIL);
            }
            mobileAuditRequestsService.finishTask(data.getHostId(), data.getTaskId(), resultGorotor);
            
        } else {
            log.warn("Dropped mobile audit task {} for user {} and host {}", data.getTaskId(), data.getUserId(), data.getHostId());
        }
        return new Result(TaskResult.SUCCESS);
    }

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

    @Override
    public Integer getMaxQueueSize() {
        return queueSizeLimit;
    }

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

    @Required
    public void setQueueSizeLimit(int queueSizeLimit) {
        this.queueSizeLimit = queueSizeLimit;
    }
}
