package ru.yandex.webmaster3.worker.camelcase;

import org.springframework.beans.factory.annotation.Required;
import ru.yandex.webmaster3.core.util.IdUtils;
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.host.moderation.camelcase.dao.HostModeratedDisplayNameYDao;
import ru.yandex.webmaster3.storage.util.ydb.exception.WebmasterYdbException;
import ru.yandex.webmaster3.storage.util.yt.YtException;
import ru.yandex.webmaster3.storage.util.yt.YtNode;
import ru.yandex.webmaster3.storage.util.yt.YtPath;
import ru.yandex.webmaster3.storage.util.yt.YtService;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

import java.util.UUID;

/**
 * @author avhaliullin
 */
public class UploadHostDisplayNamesTask extends PeriodicTask<UploadHostDisplayNamesTask.TaskState> {
    private YtService ytService;
    private HostModeratedDisplayNameYDao hostModeratedDisplayNameYDao;
    private YtPath path;

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

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

        YtPath tmpPath = YtPath.path(path.getParent(), path.getName() + "-" + System.currentTimeMillis());
        ytService.inTransaction(path).execute(cypressService -> {
            cypressService.create(tmpPath, YtNode.NodeType.TABLE, true);
            cypressService.writeTable(tmpPath, tableWriter -> {
                try {
                    hostModeratedDisplayNameYDao.forEach(request -> {
                        String value = request.getHostId().getSchema().getSchemaPrefix() +
                                request.getDisplayName() +
                                (request.getHostId().isDefaultPort() ? "" : ":" + request.getHostId().getPort());
                        tableWriter.column("key", IdUtils.hostIdToUrl(request.getHostId()));
                        tableWriter.column("subkey", "");//совместимость
                        tableWriter.column("value", value);
                        tableWriter.rowEnd();
                    });
                } catch (WebmasterYdbException | YtException e) {
                    throw new RuntimeException(e);
                }
            });
            cypressService.remove(path);
            cypressService.move(tmpPath, path, true);
            return true;
        });
        return new Result(TaskResult.SUCCESS);
    }

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

    @Required
    public void setHostModeratedDisplayNameYDao(HostModeratedDisplayNameYDao hostModeratedDisplayNameYDao) {
        this.hostModeratedDisplayNameYDao = hostModeratedDisplayNameYDao;
    }

    @Required
    public void setPath(YtPath path) {
        this.path = path;
    }

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

    public static class TaskState implements PeriodicTaskState {
        private volatile long requestsProcessed = 0;

        public void increase() {
            requestsProcessed++;
        }

        public void clear() {
            requestsProcessed = 0;
        }

        public long getRequestsProcessed() {
            return requestsProcessed;
        }
    }
}
