package io.wdd.func.auto.service;

import io.wdd.func.auto.beans.AppFunctionEnum;
import io.wdd.func.auto.beans.ProjectDeployContext;
import io.wdd.server.beans.po.ProjectInfoPO;
import io.wdd.server.coreService.CoreProjectService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class AppFuncScheduler {

    @Resource
    FuncService funcService;

    @Resource
    CoreProjectService coreProjectService;

    /**
     * 参数固定顺序为 A1C2IP SUPREME N1C2IP A1C1IP A1C1JS M2D2IP KIMMY JACLOVE
     * 1       2      3      4       5     6     7       8
     *
     * @param projectDeployContext
     * @param projectInfoPO
     * @return
     */
    private static ArrayList<String> buildAppFuncArgs(ProjectDeployContext projectDeployContext, ProjectInfoPO projectInfoPO) {

        ArrayList<String> appFuncArgs = new ArrayList<>();
        String masterIpInV4 = projectDeployContext
                .getMasterNode()
                .getServerIpInV4();
        appFuncArgs.add(masterIpInV4);
        appFuncArgs.add(projectInfoPO.getProjectNamespace());
        appFuncArgs.add(masterIpInV4);
        // A1C1IP
        if (StringUtils.isBlank(projectDeployContext
                .getMasterNode()
                .getServerIpPbV4())) {
            appFuncArgs.add(masterIpInV4);
        } else {
            appFuncArgs.add(projectDeployContext
                    .getMasterNode()
                    .getServerIpPbV4());
        }
        appFuncArgs.add(projectInfoPO.getProjectWebServicePort());
        // M2D2IP
        appFuncArgs.add(masterIpInV4);
        appFuncArgs.add(projectInfoPO.getProjectVersion());
        // jackeyLoveFile
        appFuncArgs.add("init_5.1.0.tar");

        return appFuncArgs;
    }

    public boolean runProcedure(ProjectDeployContext projectDeployContext) {

        // before run
        // check base requirement
        beforeRunProcedure(projectDeployContext);


        // during run
        doRunProcedure(projectDeployContext);


        // after run
        afterRunProcedure(projectDeployContext);


        return true;
    }

    private void beforeRunProcedure(ProjectDeployContext projectDeployContext) {

        // 检查是否符合规定

        // 检查每一个Agent是否能够连通,调用命令返回结果

        // 打印施工信息

        // 执行 基础功能施工的内容

        ProjectInfoPO projectInfoPO = coreProjectService.projectGetOne(projectDeployContext.getProjectId());
        if (ObjectUtils.isEmpty(projectInfoPO)) {
            log.error(
                    "project id of [{}] wrong ! cant find project !",
                    projectDeployContext.getProjectId()
            );
        }

        ArrayList<String> appFuncArgs = buildAppFuncArgs(
                projectDeployContext,
                projectInfoPO
        );

        projectDeployContext.setAppFunctionArgs(appFuncArgs);

        log.debug("beforeRunProcedure complete!");

    }

    private void afterRunProcedure(ProjectDeployContext projectDeployContext) {

        // 检查是否安装完成, 对安装环境进行判定
        log.debug("afterRunProcedure complete!");
    }

    private void doRunProcedure(ProjectDeployContext projectDeployContext) {

        String masterTopicName = projectDeployContext
                .getMasterNode()
                .getTopicName();

        List<AppFunctionEnum> masterAppProcedure = projectDeployContext.getMasterAppProcedure();
        if (CollectionUtils.isEmpty(masterAppProcedure)) {
            log.info("app procedure is null !");
            return;
        }

        ArrayList<String> appFunctionArgs = projectDeployContext.getAppFunctionArgs();

        for (AppFunctionEnum appFunctionEnum : masterAppProcedure) {

            // rebuild
            appFunctionArgs.add(
                    0,
                    appFunctionEnum.getAppOpname()
            );

            boolean appFuncJudge = funcService.callAppFuncAndJudge(
                    masterTopicName,
                    appFunctionEnum,
                    appFunctionArgs
            );

            if (!appFuncJudge) {
                log.error(
                        "app func of {} execute error !",
                        appFunctionEnum.getAppOpname()
                );
                return;
            }


            // must remove this one
            appFunctionArgs.remove(0);

        }

    }

}
