package cn.reghao.autodop.dmaster.app.controller.page;

import cn.reghao.autodop.dmaster.app.model.constant.AppType;
import cn.reghao.autodop.dmaster.app.model.constant.EnvList;
import cn.reghao.autodop.dmaster.app.db.query.AppBuildingQuery;
import cn.reghao.autodop.dmaster.app.db.query.AppDeployingQuery;
import cn.reghao.autodop.dmaster.app.db.query.AppRunningQuery;
import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
import cn.reghao.autodop.dmaster.app.model.po.AppDeploying;
import cn.reghao.autodop.dmaster.app.model.po.AppRunning;
import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
import cn.reghao.autodop.dmaster.app.model.po.config.DeployConfig;
import cn.reghao.autodop.dmaster.app.model.po.log.BuildLog;
import cn.reghao.autodop.dmaster.app.model.po.AppBuilding;
import cn.reghao.autodop.dmaster.app.model.po.log.BuildTime;
import cn.reghao.autodop.dmaster.app.db.repository.log.BuildLogRepository;
import cn.reghao.autodop.dmaster.app.model.vo.BuildConfig;
import cn.reghao.autodop.dmaster.rbac.UserContext;
import cn.reghao.autodop.dmaster.rbac.model.constant.RoleType;
import cn.reghao.autodop.dmaster.util.db.PageList;
import cn.reghao.autodop.dmaster.util.db.PageSort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author reghao
 * @date 2019-08-30 18:49:15
 */
@Slf4j
@Api(tags = "应用页面接口")
@Controller
@RequestMapping("/app")
public class AppPageController {
    private AppConfigQuery appConfigQuery;
    private AppBuildingQuery buildingQuery;
    private AppDeployingQuery deployingQuery;
    private AppRunningQuery runningQuery;
    private BuildLogRepository buildLogRepository;

    public AppPageController(AppConfigQuery appConfigQuery,
                             AppBuildingQuery buildingQuery,
                             AppDeployingQuery deployingQuery,
                             AppRunningQuery runningQuery,
                             BuildLogRepository buildLogRepository) {
        this.appConfigQuery = appConfigQuery;
        this.buildingQuery = buildingQuery;
        this.deployingQuery = deployingQuery;
        this.runningQuery = runningQuery;
        this.buildLogRepository = buildLogRepository;
    }

    @ApiOperation(value = "构建部署页面")
    @GetMapping("/build")
    public String buildPage(@RequestParam(value = "env", required = false) String env,
                            @RequestParam(value = "appName", required = false) String appName,
                            Model model) {
        if (env == null) {
            env = EnvList.test.name();
        }

        if (appName != null) {
            Map<String, String> map = new HashMap<>();
            map.put("appName", appName);
            List<AppBuilding> list = buildingQuery.queryAll(map);
            Page<AppBuilding> page = new PageImpl<>(list);
            PageList<AppBuilding> pageList = PageList.pageList(page);

            model.addAttribute("env", env);
            model.addAttribute("page", page);
            model.addAttribute("list", pageList.getList());
            return "/app/bd/build";
        }

        Set<String> set = new HashSet<>();
        UserContext.currentUser().getAuthorities().forEach(auth -> {
            set.add(auth.getAuthority());
        });

        String appType;
        if (set.contains(RoleType.ROLE_BACKEND.name())) {
            appType = AppType.dotnetCore.name();
        } else if (set.contains(RoleType.ROLE_FRONTEND.name())) {
            appType = AppType.npm.name();
        } else {
            appType = AppType.maven.name();
        }

        PageRequest pageRequest = PageSort.pageRequest();
        Page<AppBuilding> appBuildings;
        Map<String, String> queryMap = new HashMap<>();
        if (set.contains(RoleType.ROLE_ADMIN.name())) {
            queryMap.put("env", env);
            appBuildings = buildingQuery.queryByPage(queryMap, pageRequest);
        } else {
            queryMap.put("env", env);
            queryMap.put("appType", appType);
            appBuildings = buildingQuery.queryByPage(queryMap, pageRequest);
        }

        PageList<AppBuilding> pageList = PageList.pageList(appBuildings);
        model.addAttribute("env", env);
        model.addAttribute("page", appBuildings);
        model.addAttribute("list", pageList.getList());
        return "/app/bd/build";
    }

    @ApiOperation(value = "部署页面")
    @GetMapping("/deploy/{appId}")
    public String deployPage(@PathVariable("appId") String appId, Model model) {
        AppConfig app = appConfigQuery.findByIsDeleteFalseAndAppId(appId);
        List<DeployConfig> deployConfigs = app.getDeployConfigs();
        List<AppDeploying> list = new ArrayList<>();
        for (DeployConfig deployConfig : deployConfigs) {
            Map<String, String> queryMap = new HashMap<>();
            queryMap.put("appId", appId);
            queryMap.put("machineId", deployConfig.getMachineId());
            AppDeploying deploying = deployingQuery.query(queryMap);
            list.add(deploying);
        }

        model.addAttribute("list", list);
        return "/app/bd/deploy";
    }

    // TODO 使用 layui 弹出层
    // TODO /app/bd/buildresult 可以和 /app/bd/packscript 合并
    @ApiOperation(value = "构建日志结果页面")
    @GetMapping("/log/build/{buildLogId}/result")
    public String buildLogResultPage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
        String[] arr = buildLog.getResult().getMsg().split(System.lineSeparator());
        model.addAttribute("list", arr);
        return "/app/bd/buildresult";
    }

    @ApiOperation(value = "构建日志页面")
    @GetMapping("/log/build")
    public String buildLogPage(Model model) {
        PageRequest pageRequest = PageSort.pageRequest();
        Page<BuildLog> buildLogs = buildLogRepository.findAll(pageRequest);
        PageList<BuildLog> pageList = PageList.pageList(buildLogs);

        model.addAttribute("page", buildLogs);
        model.addAttribute("list", pageList.getList());
        return "/app/bd/buildlog";
    }

    // TODO 使用 layui 弹出层
    @ApiOperation(value = "构建配置页面")
    @GetMapping("/log/build/{buildLogId}/buildconfig")
    public String buildConfigPage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
        BuildConfig buildConfig = buildLog.getBuildConfig();
        model.addAttribute("buildConfig", buildConfig);
        return "/app/bd/buildconfig";
    }

    // TODO 使用 layui 弹出层
    @ApiOperation(value = "打包脚本页面")
    @GetMapping("/log/build/{buildLogId}/packscript")
    public String packScriptPage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
        String[] arr = buildLog.getPackScript().split(System.lineSeparator());
        model.addAttribute("list", arr);
        return "/app/bd/packscript";
    }

    // TODO 使用 layui 弹出层
    @ApiOperation(value = "版本信息页面")
    @GetMapping("/log/build/{buildLogId}/commitinfo")
    public String commitInfoPage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
        model.addAttribute("commitInfo", buildLog.getCommitInfo());
        return "/app/bd/commitinfo";
    }

    // TODO 使用 layui 弹出层
    @ApiOperation(value = "构建时间页面")
    @GetMapping("/log/build/{buildLogId}/buildtime")
    public String buildTimePage(@PathVariable("buildLogId") BuildLog buildLog, Model model) {
        BuildTime buildTime = buildLog.getBuildTime();
        model.addAttribute("buildTime", buildTime);
        return "/app/bd/buildtime";
    }

    @ApiOperation(value = "应用运行状态页面")
    @GetMapping("/status")
    public String statusPage(@RequestParam(value = "env", required = false) String env,
                             @RequestParam(value = "appName", required = false) String appName,
                             Model model) {
        if (env == null) {
            env = EnvList.test.name();
        }

        if (appName != null) {
            Map<String, String> map = new HashMap<>();
            map.put("appName", appName);
            List<AppRunning> list = runningQuery.queryAll(map);
            Page<AppRunning> page = new PageImpl<>(list);
            PageList<AppRunning> pageList = PageList.pageList(page);

            model.addAttribute("env", env);
            model.addAttribute("page", page);
            model.addAttribute("list", pageList.getList());
            return "/app/status";
        }

        Map<String, String> queryMap = new HashMap<>();
        queryMap.put("env", env);
        PageRequest pageRequest = PageSort.pageRequest();
        Page<AppRunning> appRunnings = runningQuery.queryByPage(queryMap, pageRequest);
        PageList<AppRunning> pageList = PageList.pageList(appRunnings);

        model.addAttribute("env", env);
        model.addAttribute("page", appRunnings);
        model.addAttribute("list", pageList.getList());
        return "/app/status/appstatus";
    }

    @ApiOperation(value = "应用运行日志页面")
    @GetMapping("/status/applog/{appId}/{machineId}")
    public String appLogPage(@PathVariable("appId") String appId,
                             @PathVariable("machineId") String machineId,
                             Model model) {
        return "/app/status/applog";
    }
}
