package ru.yandex.webmaster3.worker.turbo.autodelete;

import java.util.Map;
import java.util.UUID;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.turbo.dao.autodelete.TurboAutoDeletedPagesSamplesYDao;
import ru.yandex.webmaster3.storage.util.ydb.YdbYqlService;
import ru.yandex.webmaster3.storage.util.yt.YtPath;
import ru.yandex.webmaster3.storage.yql.YqlFunctions;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

/**
 * Created by Oleg Bazdyrev on 19/02/2021.
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class ImportTurboAutoDeletedPagesSamplesTask extends PeriodicTask<PeriodicTaskState> {

    public static final String QUERY_PREFIX = "\n" +
            "PRAGMA yt.ForceInferSchema;\n" +
            "$current_timestamp = ${CURRENT_TIMESTAMP}ul;\n" +
            "$update_date = DateTime::FromMilliseconds(cast($current_timestamp as Uint64));\n" +
            YqlFunctions.CUT_WWW_AND_M.getFunctionDef() + "\n";

    public static final String DATA_SELECT_QUERY =  "SELECT \n" +
                    "            cast(host as Utf8) as domain,\n" +
                    "            cast(severity as Int32) as severity,\n" +
                    "            cast(DateTime::FromSeconds(cast(ts as UInt32)) as Timestamp) as ts,\n" +
                    "            cast($update_date as Timestamp) as table_ts,\n" +
                    "            cast(DateTime::FromSeconds(cast(last_check_ts as UInt32)) as Timestamp) as last_check_ts,\n" +
                    "            cast(DateTime::FromSeconds(cast(deadline_ts as UInt32)) as Timestamp) as deadline_ts,\n" +
                    "            cast(Yson::SerializeJson(errors) as Json) as errors\n" +
                    "        FROM ${SOURCE_TABLE}";

    private final TurboAutoDeletedPagesSamplesYDao turboAutoDeletedPagesSamplesYDao;
    private final YdbYqlService ydbYqlService;

    @Value("${webmaster3.worker.turbo.autoDeletedSamples.path}")
    private YtPath samplesPath;

    @Override
    public Result run(UUID runId) throws Exception {
        DateTime now = DateTime.now();
        StrSubstitutor substitutor = new StrSubstitutor(Map.of(
                "CURRENT_TIMESTAMP", String.valueOf(now.getMillis()),
                "SOURCE_TABLE", samplesPath.toYqlPath()
        ));

        ydbYqlService.importToYdb(turboAutoDeletedPagesSamplesYDao.getTablePath(), substitutor.replace(DATA_SELECT_QUERY), substitutor.replace(QUERY_PREFIX));
        turboAutoDeletedPagesSamplesYDao.clearOldRecords(now);
        return new Result(TaskResult.SUCCESS);
    }

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

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