package cn.reghao.devops.mgr.app.controller.page;

import cn.reghao.devops.mgr.app.db.query.AppBuildQuery;
import cn.reghao.devops.mgr.build.db.repository.CompilerConfigRepository;
import cn.reghao.devops.mgr.build.db.repository.PackerConfigRepository;
import cn.reghao.devops.mgr.build.db.repository.RepoAuthConfigRepository;
import cn.reghao.devops.mgr.app.model.constant.AppType;
import cn.reghao.devops.mgr.app.model.po.config.AppConfig;
import cn.reghao.devops.mgr.app.model.vo.AppConfigVO;
import cn.reghao.devops.common.util.KeyValue;
import cn.reghao.devops.mgr.builder.model.constant.EnvType;
import cn.reghao.devops.mgr.util.DefaultSetting;
import cn.reghao.devops.mgr.util.PageSort;
import cn.reghao.devops.common.msg.constant.PackType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2019-08-30 18:49:15
 */
@Slf4j
@Api(tags = "应用配置页面")
@Controller
@RequestMapping("/app/config/app")
public class AppConfigPageController {
    private final AppBuildQuery appBuildQuery;
    private final RepoAuthConfigRepository repoAuthConfigRepository;
    private final CompilerConfigRepository compilerConfigRepository;
    private final PackerConfigRepository packerConfigRepository;

    public AppConfigPageController(AppBuildQuery appBuildQuery,
                                   RepoAuthConfigRepository repoAuthConfigRepository,
                                   CompilerConfigRepository compilerConfigRepository,
                                   PackerConfigRepository packerConfigRepository) {
        this.appBuildQuery = appBuildQuery;
        this.repoAuthConfigRepository = repoAuthConfigRepository;
        this.compilerConfigRepository = compilerConfigRepository;
        this.packerConfigRepository = packerConfigRepository;
    }

    @ApiOperation(value = "应用配置列表页面", notes = "N")
    @GetMapping
    public String appConfigPage(@RequestParam(value = "env", required = false) String env,
                                @RequestParam(value = "type", required = false) String type,
                                @RequestParam(value = "appName", required = false) String appName,
                                Model model) {
        if (env == null) {
            env = DefaultSetting.getDefaultEnv();
        }

        if (type == null) {
            type = DefaultSetting.getDefaultAppType();
        }

        if (appName != null) {
            Map<String, String> map = new HashMap<>();
            map.put("appName", appName);
            PageRequest pageRequest = PageRequest.of(0, 10);
            Page<AppConfig> page = appBuildQuery.queryByFields(map, pageRequest);
            model.addAttribute("env", env);
            model.addAttribute("type", type);
            model.addAttribute("page", page);
            model.addAttribute("list", page.getContent());
            return "/devops/app/config/index";
        }

        PageRequest pageRequest = PageSort.pageRequest();
        Page<AppConfigVO> appPage = appBuildQuery.getByEnvAndType(env, type, pageRequest);

        model.addAttribute("env", env);
        model.addAttribute("type", type);
        model.addAttribute("page", appPage);
        model.addAttribute("list", appPage.getContent());
        return "/devops/app/config/index";
    }

    @ApiOperation(value = "添加应用配置页面", notes = "N")
    @GetMapping("/add")
    public String addAppConfigPage(Model model) {
        setAppModel(model);
        return "/devops/app/config/add";
    }

    private void setAppModel(Model model) {
        List<KeyValue> packTypes = new ArrayList<>();
        packTypes.add(new KeyValue("请选择打包类型", ""));
        for (PackType packType : PackType.values()) {
            packTypes.add(new KeyValue(packType.name(), packType.name()));
        }

        model.addAttribute("packTypes", packTypes);
        setCommon(model);
    }

    private void setCommon(Model model) {
        List<KeyValue> envs = getEnvList();
        List<KeyValue> appTypes = new ArrayList<>();
        for (AppType appType : AppType.values()) {
            appTypes.add(new KeyValue(appType.name(), appType.name()));
        }
        model.addAttribute("environments", envs);
        model.addAttribute("appTypes", appTypes);

        List<KeyValue> repoAuths = repoAuthConfigRepository.findAll().stream()
                .map(repoAuthConfig -> new KeyValue(String.valueOf(repoAuthConfig.getName()), repoAuthConfig.getName()))
                .collect(Collectors.toList());

        List<KeyValue> compilers = compilerConfigRepository.findAllByDeletedFalse().stream()
                .map(compilerConfig -> new KeyValue(String.valueOf(compilerConfig.getName()), compilerConfig.getName()))
                .collect(Collectors.toList());

        List<KeyValue> packers = packerConfigRepository.findAllByDeletedFalse().stream()
                .map(packerConfig -> new KeyValue(String.valueOf(packerConfig.getName()), packerConfig.getName()))
                .collect(Collectors.toList());
        model.addAttribute("repoAuths", repoAuths);
        model.addAttribute("compilers", compilers);
        model.addAttribute("packers", packers);
    }

    @ApiOperation(value = "编辑应用配置页面", notes = "N")
    @GetMapping("/edit/{id}")
    public String editAppConfigPage(@PathVariable("id") AppConfig app, Model model) {
        setAppModel(model);
        model.addAttribute("app", app);
        return "/devops/app/config/edit";
    }

    @ApiOperation(value = "拷贝应用配置页面", notes = "N")
    @GetMapping("/copy/{appId}")
    public String copyAppConfigPage(@PathVariable("appId") String appId, Model model) {
        List<KeyValue> envs = getEnvList();
        model.addAttribute("environments", envs);
        model.addAttribute("appId", appId);
        return "/devops/app/config/copy";
    }

    private List<KeyValue> getEnvList() {
        List<KeyValue> envs = new ArrayList<>();
        for (EnvType envType : EnvType.values()) {
            envs.add(new KeyValue(envType.name(), envType.name()));
        }

        return envs;
    }

    @ApiOperation(value = "应用配置详情页面", notes = "N")
    @GetMapping("/detail/{appId}")
    public String appConfigPage(@PathVariable("appId") String appId, Model model) {
        AppConfig app = appBuildQuery.getAppConfig(appId);
        model.addAttribute("app", app);
        return "/devops/app/config/detail";
    }
}
