package ru.yandex.webmaster3.worker.extended.http.codes.export;

import org.springframework.beans.factory.annotation.Required;
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.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 ru.yandex.wmtools.common.util.http.YandexHttpStatus;

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

/**
 * User: azakharov
 * Date: 14.05.15
 * Time: 13:03
 */
public class ExtendedHttpCodesExportTask extends PeriodicTask<ExtendedHttpCodesExportTask.TaskState> {
    private static final String CODE_NONE = "-";
    private static final String CODE_200 = "200";

    private YtService ytService;
    private YtPath tablePath;

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

    @Override
    public Result run(UUID runId) throws Exception {
        LinkedHashMap<Integer, String> codes = new LinkedHashMap<>();

        for (int i = 0; i < 1000; i++) {
            codes.put(i, String.valueOf(i));
        }
        for (YandexHttpStatus status : YandexHttpStatus.values()) {
            int value = status.getCode();
            if (value >= 1000) {
                if (value < 2000) {
                    codes.put(value, CODE_NONE);
                } else if (value < 3000) {
                    if (status == YandexHttpStatus.EXT_HTTP_2021_CLEANPARAM) {
                        codes.put(value, CODE_NONE);
                    } else {
                        codes.put(value, CODE_200);
                    }
                } else if (value < 4000) {
                    codes.put(value, CODE_NONE);
                }
            }
        }

        YtPath tmpPath = YtPath.path(tablePath.getParent(), tablePath.getName() + "-" + System.currentTimeMillis());
        ytService.inTransaction(tablePath).execute(cypressService -> {
            cypressService.create(tmpPath, YtNode.NodeType.TABLE, true);
            cypressService.writeTable(tmpPath, tableWriter -> {
                for (Map.Entry<Integer, String> visibleStatus : codes.entrySet()) {
                    try {
                        tableWriter.column("key", Integer.toString(visibleStatus.getKey()));
                        tableWriter.column("value", visibleStatus.getValue());
                        tableWriter.rowEnd();
                    } catch (YtException e) {
                        throw new RuntimeException("Unable to write webmaster extended http codes to yt", e);
                    }
                }
            });
            cypressService.remove(tablePath);
            cypressService.move(tmpPath, tablePath, true);
            return true;
        });
        return new Result(TaskResult.SUCCESS);
    }

    public static class TaskState implements PeriodicTaskState {
    }

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

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

    @Required
    public void setTablePath(YtPath tablePath) {
        this.tablePath = tablePath;
    }
}
