package ru.yandex.webmaster3.worker.host.verification;

import java.util.Optional;
import java.util.UUID;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.util.json.JsonMapping;
import ru.yandex.webmaster3.core.worker.client.WorkerClient;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.core.worker.task.VerifyHostTaskData;
import ru.yandex.webmaster3.storage.host.CommonDataState;
import ru.yandex.webmaster3.storage.host.CommonDataType;
import ru.yandex.webmaster3.storage.postpone.PostponeActionYDao;
import ru.yandex.webmaster3.storage.postpone.PostponeOperationType;
import ru.yandex.webmaster3.storage.settings.dao.CommonDataStateYDao;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

/**
 * ishalaru
 * 13.01.2021
 **/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class VerifyPostponedTaskCheckTask extends PeriodicTask<VerifyPostponedTaskCheckTask.TaskState> {
    private final CommonDataStateYDao commonDataStateYDao;
    private final PostponeActionYDao postponeActionYDao;
    private final WorkerClient workerClient;

    @Override
    public Result run(UUID runId) throws Exception {
        setState(new TaskState());
        final DateTime lastProcessedDate = Optional.ofNullable(commonDataStateYDao.getValue(CommonDataType.LAST_POSTPONED_HOST_VERIFY_PROCESSED))
                .map(CommonDataState::getValue)
                .map(DateTime::parse)
                .orElse(new DateTime(2021, 01, 01, 0, 0));
        DateTime curDate = DateTime.now();
        state.date = curDate.toString();
        postponeActionYDao.loadPostponedData(postponeData -> {
            if (postponeData.getType() == PostponeOperationType.VERIFY_HOST &&
                    postponeData.getDate().isAfter(lastProcessedDate) && (postponeData.getDate().isBefore(curDate) ||
                    postponeData.getDate().isEqual(curDate))) {
                state.processed++;

                final VerifyHostTaskData verifyHostTaskData = JsonMapping.readValue(postponeData.getData(), VerifyHostTaskData.class);
                workerClient.checkedEnqueueTask(verifyHostTaskData);
                postponeActionYDao.delete(postponeData);
            }
            state.totalScanned++;
        });
        commonDataStateYDao.update(new CommonDataState(CommonDataType.LAST_POSTPONED_HOST_VERIFY_PROCESSED, curDate.toString(), new DateTime()));
        return Result.SUCCESS;
    }

    @Override
    public PeriodicTaskType getType() {
        return PeriodicTaskType.POSTPONED_VERIFY_HOST;
    }

    @Override
    public TaskSchedule getSchedule() {
        return TaskSchedule.startByCron("0 0/10 * * * *");
    }

    public class TaskState implements PeriodicTaskState {
        @Getter
        long totalScanned;
        @Getter
        long processed;
        @Getter
        String date;
    }
}
