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

import cn.reghao.autodop.common.msg.rpc.dto.app.PackType;
import cn.reghao.autodop.dmaster.app.model.constant.AppType;
import cn.reghao.autodop.dmaster.app.model.constant.EnvList;
import cn.reghao.autodop.dmaster.app.model.po.config.DeployConfig;
import cn.reghao.autodop.dmaster.machine.db.query.MachineHostQuery;
import cn.reghao.autodop.dmaster.notification.model.po.NotifyGroup;
import cn.reghao.autodop.dmaster.notification.model.po.NotifyType;
import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
import cn.reghao.autodop.dmaster.app.db.query.config.CompilerConfigQuery;
import cn.reghao.autodop.dmaster.app.db.query.config.PackerConfigQuery;
import cn.reghao.autodop.dmaster.app.db.query.config.RepoAuthConfigQuery;
import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
import cn.reghao.autodop.dmaster.app.model.vo.KeyValue;
import cn.reghao.autodop.dmaster.notification.db.repository.NotifyGroupRepository;
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.Page;
import org.springframework.data.domain.PageImpl;
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 AppConfigQuery appConfigQuery;
    private final RepoAuthConfigQuery repoAuthConfigQuery;
    private final CompilerConfigQuery compilerConfigQuery;
    private final PackerConfigQuery packerConfigQuery;
    private final MachineHostQuery hostQuery;
    private final NotifyGroupRepository receiverRepository;

    public AppConfigPageController(AppConfigQuery appConfigQuery, RepoAuthConfigQuery repoAuthConfigQuery,
                                   CompilerConfigQuery compilerConfigQuery, PackerConfigQuery packerConfigQuery, MachineHostQuery hostQuery,
                                   NotifyGroupRepository receiverRepository) {
        this.appConfigQuery = appConfigQuery;
        this.repoAuthConfigQuery = repoAuthConfigQuery;
        this.compilerConfigQuery = compilerConfigQuery;
        this.packerConfigQuery = packerConfigQuery;
        this.hostQuery = hostQuery;
        this.receiverRepository = receiverRepository;
    }

    @ApiOperation(value = "应用配置页面")
    @GetMapping
    public String appConfigPage(@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<AppConfig> list = appConfigQuery.query(map);
            Page<AppConfig> page = new PageImpl<>(list);
            PageList<AppConfig> pageList = PageList.pageList(page);

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

        PageRequest pageRequest = PageSort.pageRequest();
        Page<AppConfig> appPage = appConfigQuery.findByEnv(env, pageRequest);
        PageList<AppConfig> pageList = PageList.pageList(appPage);

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

    @GetMapping("/add")
    public String addAppConfigPage(Model model) {
        setAppModel(model);
        return "/app/config/app/add";
    }

    private void setAppModel(Model model) {
        List<KeyValue> notifyTypes = new ArrayList<>();
        notifyTypes.add(new KeyValue("请选择通知类型", ""));
        for (NotifyType notifyType : NotifyType.values()) {
            notifyTypes.add(new KeyValue(notifyType.name(), notifyType.name()));
        }

        List<KeyValue> machineList = hostQuery.findByEnv(EnvList.test.name()).stream()
                .map(machineHost -> {
                    String machineId = machineHost.getMachineId();
                    String machineIpv4 = machineHost.getMachineIpv4();
                    return new KeyValue(machineId, machineIpv4);
                })
                .collect(Collectors.toList());
        List<KeyValue> machines = new ArrayList<>();
        machines.add(new KeyValue("", "请选择部署的机器"));
        machines.addAll(machineList);

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

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

    private void setCommon(Model model) {
        List<KeyValue> envs = new ArrayList<>();
        for (EnvList envList : EnvList.values()) {
            envs.add(new KeyValue(envList.name(), envList.name()));
        }

        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 = repoAuthConfigQuery.findAll().stream()
                .map(repoAuthConfig -> new KeyValue(String.valueOf(repoAuthConfig.getName()), repoAuthConfig.getName()))
                .collect(Collectors.toList());

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

        List<KeyValue> packers = packerConfigQuery.findAllByIsDeleteFalse().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);
    }

    @GetMapping("/edit/{id}")
    public String editAppConfigPage(@PathVariable("id") AppConfig app, Model model) {
        setAppModel(model);
        model.addAttribute("app", app);
        return "/app/config/app/add";
    }

    @GetMapping("/copy/{id}")
    public String copyAppConfigPage(@PathVariable("id") AppConfig app, Model model) {
        model.addAttribute("app", app);
        return "/app/config/app/copy";
    }

    @GetMapping("/detail/{appId}")
    public String appConfigPage(@PathVariable("appId") String appId, Model model) {
        AppConfig app = appConfigQuery.findByAppId(appId);
        model.addAttribute("app", app);
        return "/app/config/app/detail";
    }

    @ApiOperation(value = "通知配置页面")
    @GetMapping("/notify/{id}")
    public String receiverIdsPage(@PathVariable("id") AppConfig app, Model model) {
        Set<NotifyGroup> currentSet = new HashSet<>(app.getNotifyGroups());
        List<NotifyGroup> list = receiverRepository.findAll();

        model.addAttribute("id", app.getId());
        model.addAttribute("currentSet", currentSet);
        model.addAttribute("list", list);
        return "/app/config/app/notify";
    }

    @ApiOperation(value = "部署配置页面")
    @GetMapping("/deploy/{id}")
    public String deployConfigPage(@PathVariable("id") AppConfig app, Model model) {
        int id = app.getId();
        String packType = app.getPackerConfig().getType();
        List<DeployConfig> list = app.getDeployConfigs();
        if (list == null) {
            list = Collections.emptyList();
        }

        List<KeyValue> machines = hostQuery.findByEnv(EnvList.test.name()).stream()
                .map(machineHost -> {
                    String machineId = machineHost.getMachineId();
                    String machineIpv4 = machineHost.getMachineIpv4();
                    return new KeyValue(machineId, machineIpv4);
                })
                .collect(Collectors.toList());

        model.addAttribute("id", id);
        model.addAttribute("packType", packType);
        model.addAttribute("machines", machines);
        model.addAttribute("list", list);
        return "/app/config/app/deploy";
    }
}
