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

import cn.reghao.devops.common.util.KeyValue;
import cn.reghao.devops.mgr.machine.db.query.MachineQuery;
import cn.reghao.devops.mgr.machine.model.po.MachineInfo;
import cn.reghao.devops.mgr.util.DefaultSetting;
import cn.reghao.devops.mgr.util.PageSort;
import cn.reghao.devops.mgr.builder.model.constant.EnvType;
import cn.reghao.devops.mgr.machine.model.SshConnData;
import cn.reghao.devops.mgr.machine.model.po.MachineHost;
import cn.reghao.devops.mgr.machine.model.po.SshAuth;
import cn.reghao.devops.mgr.machine.model.vo.MachineHostVO;
import cn.reghao.devops.mgr.machine.model.vo.MachineInfoVO;
import cn.reghao.devops.mgr.machine.model.vo.MachineSshAuth;
import cn.reghao.devops.mgr.machine.util.Keys;
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.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

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

/**
 * @author reghao
 * @date 2019-08-30 18:49:15
 */
@Slf4j
@Api(tags = "机器节点页面")
@Controller
@RequestMapping("/machine/host")
public class MachineHostPageController {
    private final MachineQuery machineQuery;

    public MachineHostPageController(MachineQuery machineQuery) {
        this.machineQuery = machineQuery;
    }

    @ApiOperation(value = "机器节点页面", notes = "N")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping
    public String indexPage(@RequestParam(value = "env", required = false) String env,
                           @RequestParam(value = "machineIpv4", required = false) String machineIpv4,
                           Model model) {
        if (env == null) {
            env = DefaultSetting.getDefaultEnv();
        }

        PageRequest pageRequest = PageSort.pageRequest();
        Page<MachineHostVO> page;
        if (machineIpv4 != null) {
            //page = machineQuery.searchResultPage(machineIpv4);
            page = Page.empty();
        } else {
            page = machineQuery.getMachineHostByPage(env, pageRequest);
        }
        model.addAttribute("env", env);
        model.addAttribute("page", page);
        model.addAttribute("list", page.getContent());
        return "/devops/machine/host/index";
    }

    @ApiOperation(value = "使用某机器的应用列表页面", notes = "N")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/app/{machineId}")
    public String machineAppPage(@PathVariable("machineId") String machineId, Model model) {
        List<KeyValue> list = machineQuery.getMachineApps(machineId);
        model.addAttribute("list", list);
        return "/devops/machine/host/apps";
    }

    @ApiOperation(value = "机器所属环境设置页面", notes = "N")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/env/{machineId}")
    public String hostEditPage(@PathVariable("machineId") String machineId, Model model) {
        List<KeyValue> envs = new ArrayList<>();
        for (EnvType envType : EnvType.values()) {
            envs.add(new KeyValue(envType.name(), envType.name()));
        }

        MachineHost machineHost = machineQuery.getMachineHost(machineId);
        String env = machineHost.getEnv();
        model.addAttribute("machineId", machineId);
        model.addAttribute("environments", envs);
        model.addAttribute("env", env);
        return "/devops/machine/host/env";
    }

    @ApiOperation(value = "SSH 认证设置页面", notes = "N")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/sshauth/{machineId}")
    public String sshAuthPage(@PathVariable("machineId") String machineId, Model model) {
        MachineSshAuth machineSshAuth = machineQuery.getMachineSshAuth(machineId);
        List<KeyValue> ipv4List = machineSshAuth.getIpv4List().stream()
                .map(ipv4 -> new KeyValue(ipv4, ipv4)).collect(Collectors.toList());

        String machineIpv4;
        SshAuth sshAuth = machineSshAuth.getSshAuth();
        if (sshAuth != null) {
            machineIpv4 = sshAuth.getIpv4();
        } else {
            machineIpv4 = ipv4List.get(0).getValue();
        }

        model.addAttribute("machineId", machineId);
        model.addAttribute("machineIpv4", machineIpv4);
        model.addAttribute("ipv4List", ipv4List);
        model.addAttribute("sshAuth", machineSshAuth.getSshAuth());
        return "/devops/machine/host/sshauth";
    }

    @ApiOperation(value = "SSH 控制台页面", notes = "N")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/webssh/{machineId}")
    public String webSshPage(@PathVariable("machineId") String machineId, Model model) {
        MachineHost machineHost = machineQuery.getMachineHost(machineId);
        SshAuth sshAuth = machineHost.getSshAuth();
        if (sshAuth == null) {
            String errMsg = "先设置 SSH 认证";
            model.addAttribute("errMsg", errMsg);
            return "/error";
        }

        SshConnData sshConnData = new SshConnData();
        sshConnData.setOps(Keys.OPS_CONNECT);
        sshConnData.setHost(sshAuth.getIpv4());
        sshConnData.setPort(sshAuth.getPort());
        sshConnData.setUsername(sshAuth.getUsername());
        sshConnData.setPassword(sshAuth.getPassword());

        model.addAttribute("sshConnData", sshConnData);
        return "/devops/machine/host/webssh";
    }

    @ApiOperation(value = "机器信息详情页面", notes = "N")
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @GetMapping("/detail/{machineId}")
    public String getMachineInfo(@PathVariable("machineId") String machineId, Model model) {
        MachineInfo machineInfo = machineQuery.getMachineInfo(machineId);
        if (machineInfo == null) {

        }

        model.addAttribute("machine", new MachineInfoVO(machineInfo));
        return "/devops/machine/host/detail";
    }
}
