package com.lanyuanxiaoyao.service.command.commands;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.lanyuanxiaoyao.service.command.utils.CommandLineUtils;
import com.lanyuanxiaoyao.service.command.utils.TableUtils;
import com.lanyuanxiaoyao.service.common.Constants;
import com.lanyuanxiaoyao.service.common.entity.TableMeta;
import com.lanyuanxiaoyao.service.configuration.entity.yarn.YarnClusters;
import com.lanyuanxiaoyao.service.forest.service.InfoService;
import com.lanyuanxiaoyao.service.forest.service.ScheduleService;
import com.lanyuanxiaoyao.service.forest.service.launcher.LaunchersService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;

/**
 * 压缩相关操作
 *
 * @author lanyuanxiaoyao
 * @date 2024-03-19
 */
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@ShellComponent("压缩任务相关操作")
public class CompactionCommand extends AbstractUtilShellComponent {
    private static final Logger logger = LoggerFactory.getLogger(CompactionCommand.class);
    private final static String RUN_CONFIRMATION_MESSAGE = "操作将会提交压缩任务, 请再次确认操作";

    private final InfoService infoService;
    private final ScheduleService scheduleService;
    private final YarnClusters yarnClusters;
    private final LaunchersService launchersService;

    public CompactionCommand(InfoService infoService, ScheduleService scheduleService, YarnClusters yarnClusters, LaunchersService launchersService) {
        this.infoService = infoService;
        this.scheduleService = scheduleService;
        this.yarnClusters = yarnClusters;
        this.launchersService = launchersService;
    }

    @ShellMethod("启动全部表压缩")
    public void compactionAll() {
        scheduleService.scheduleAllTable();
    }

    @ShellMethod("启动全部重点表压缩")
    public void compactionAllForce() {
        scheduleService.scheduleAllFocus();
    }

    @ShellMethod("启动表压缩任务")
    public String compactionRun(
            @ShellOption(help = "Flink job id") Long flinkJobId,
            @ShellOption(help = "别名") String alias,
            @ShellOption(
                    help = "Ignore double check",
                    defaultValue = "false"
            ) Boolean ignoreCheck
    ) {
        TableMeta meta = infoService.tableMetaDetail(flinkJobId, alias);
        return CommandLineUtils.generateResultLines(
                () -> {
                    if (ObjectUtil.isEmpty(meta)) {
                        return "没有找到指定的表信息";
                    } else {
                        System.out.println(TableUtils.makeTableMeta(meta));
                        if (doubleCheck(RUN_CONFIRMATION_MESSAGE, ignoreCheck)) {
                            scheduleService.scheduleTable(meta.getJob().getId(), meta.getAlias());
                            return Constants.OPERATION_DONE;
                        } else {
                            return Constants.OPERATION_CANCEL;
                        }
                    }
                }
        );
    }

    @ShellMethod("启动表压缩任务")
    public String compactionDryRun(
            @ShellOption(
                    help = "集群",
                    defaultValue = ""
            ) String cluster,
            @ShellOption(help = "Flink job id") Long flinkJobId,
            @ShellOption(help = "别名") String alias,
            @ShellOption(
                    help = "Ignore double check",
                    defaultValue = "false"
            ) Boolean ignoreCheck
    ) {
        if (StrUtil.isBlank(cluster)) {
            cluster = yarnClusters.getDefaultCompactionCluster();
            logger.info("Use default compaction cluster: {}", cluster);
        }
        String targetCluster = cluster;
        TableMeta meta = infoService.tableMetaDetail(flinkJobId, alias);
        return CommandLineUtils.generateResultLines(
                () -> {
                    if (ObjectUtil.isEmpty(meta)) {
                        return "没有找到指定的表信息";
                    } else {
                        System.out.println(TableUtils.makeTableMeta(meta));
                        if (doubleCheck(RUN_CONFIRMATION_MESSAGE, ignoreCheck)) {
                            launchersService.compactionStart(targetCluster, flinkJobId, alias);
                            return Constants.OPERATION_DONE;
                        } else {
                            return Constants.OPERATION_CANCEL;
                        }
                    }
                }
        );
    }
}
