package ru.yandex.webmaster3.worker.digest.notificationsettings;

import org.joda.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Required;
import ru.yandex.webmaster3.core.util.RetryUtils;
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.util.yt.*;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

import java.util.List;
import java.util.UUID;

/**
 * Created by ifilippov5 on 29.08.17.
 */
public class UploadUserNotificationSettingsTask extends PeriodicTask<UploadUserNotificationSettingsTask.TaskState> {
    private static final Logger log = LoggerFactory.getLogger(UploadUserNotificationSettingsTask.class);

    private static final RetryUtils.RetryPolicy RETRY_POLICY = RetryUtils.linearBackoff(10, Duration.standardMinutes(2));
    private static final String TABLE_NAME = "user-notification-channel-settings";
    private static final String TABLE_SCHEMA = "[" +
            "{'name': 'user_id', 'type': 'uint64'}, " +
            "{'name': 'login', 'type': 'string'}, " +
            "{'name': 'email', 'type': 'string'}, " +
            "{'name': 'language', 'type': 'string'}, " +
            "{'name': 'fio', 'type': 'string'}, " +
            "{'name': 'host_id', 'type': 'string'}, " +
            "{'name': 'notification_type', 'type': 'string'}, " +
            "{'name': 'channel_service', 'type': 'boolean'}, " +
            "{'name': 'channel_email', 'type': 'boolean'}," +
            "{'name': 'channel_sup', 'type': 'boolean'}]";

    private List<YtPath> workDirs;
    private YtService ytService;

    private UserNotificationSettingsBuildService userNotificationSettingsBuildService;

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

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

    @Override
    public PeriodicTask.Result run(UUID runId) throws Exception {
        state = new UploadUserNotificationSettingsTask.TaskState();
        setState(state);

        YtTableData table = null;
        try {
            table = ytService.prepareTableData(TABLE_NAME, (tw) -> {
                userNotificationSettingsBuildService.upload(tw);
            });

            for (YtPath workDir : workDirs) {
                YtPath tablePath = YtPath.path(workDir, TABLE_NAME);
                YtTransactionService.TransactionProcess process = new YtUtils.TransactionWriterBuilder(tablePath, table)
                        .withSchema(TABLE_SCHEMA)
                        .withRetry(RETRY_POLICY)
                        .build();

                YtUtils.TransactionExecutor writer = new YtUtils.TransactionExecutor(ytService, workDir);
                writer.execute(process);
            }
        } finally {
            if (table != null) {
                table.delete();
            }
        }
        return new PeriodicTask.Result(TaskResult.SUCCESS);
    }

    public static class TaskState implements PeriodicTaskState {
    }

    @Required
    public void setWorkDirs(List<YtPath> workDirs) {
        this.workDirs = workDirs;
    }

    @Required
    public void setYtService(YtService ytService) {
        this.ytService = ytService;
    }

    @Required
    public void setUserNotificationSettingsBuildService(UserNotificationSettingsBuildService userNotificationSettingsBuildService) {
        this.userNotificationSettingsBuildService = userNotificationSettingsBuildService;
    }
}
