package com.bocloud.ims.service.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.ims.common.utils.FastjsonUtils;
import com.bocloud.ims.entity.common.Project;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.service.internal.SmsProjectService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 齐治堡垒机服务类
 *
 * @author sxp
 * @since 2023/8/25
 */
@Service
public class ShtermService {
    private static Logger logger = LoggerFactory.getLogger(ShtermService.class);

    @Autowired
    private SmsProjectService smsProjectService;
    @Autowired
    private AmqpTemplate amqpTemplate;


    /**
     * 向堡垒机发送新增云主机的消息
     * <p>
     * 发送数据到mq
     * </p>
     *
     * @author lxy
     * @since 2021/5/13
     * @since 2023/8/25 modify by sxp 堡垒机相关的代码放在这里
     **/
    public void addShterm(CloudServer cloudServer) {
        String privateIps = cloudServer.getPrivateIps();
        if (StringUtils.isEmpty(privateIps)) {
            return;
        }

        Long projectId = cloudServer.getProjectId();
        Long ownerId = cloudServer.getOwnerId();
        String osCategory = cloudServer.getOsCategory();
        String type = "LINUX".equalsIgnoreCase(osCategory) ? osCategory : "WINDOWS";
        String username = "LINUX".equalsIgnoreCase(osCategory) ? "root" : "administrator";
        String passwordDes = cloudServer.getPassword();
        String vendorName = cloudServer.getVendorName();

        try {
            String projectName = "";
            if (projectId != null && projectId.longValue() > 0) {
                BocloudResult<Project> projectResult = smsProjectService.detail(projectId);
                if (projectResult.isSuccess()) {
                    Project project = projectResult.getData();
                    if (null != project) {
                        projectName = project.getName();
                    }
                }
            }

            // 堡垒机中资产的简要说明 sxp:2023.8.25
            StringBuilder descBuffer = new StringBuilder();
            if (StringUtils.isNotEmpty(projectName)) {
                descBuffer.append(projectName).append('，');
            }
            if (StringUtils.isNotEmpty(vendorName)) {
                descBuffer.append(vendorName).append('，');
            }
            if (descBuffer.length() > 0) {
                descBuffer.setLength(descBuffer.length() - 1);
            }

            String vendorType = cloudServer.getVendorType();

            List<String> ipList = new ArrayList<>();
            if (CloudProvider.VMWARE.name().equals(vendorType)) {
                ipList = getVmwareIpList(privateIps);
            } else if (CloudProvider.SANGFOR.name().equals(vendorType)) {
                ipList = getSangforIpList(cloudServer, privateIps);
            } else {
                ipList.add(cloudServer.getManagerIp());
            }

            for (String ip : ipList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name", cloudServer.getName());
                jsonObject.put("password", passwordDes);
                jsonObject.put("privateIps", ip);
                jsonObject.put("username", username);
                jsonObject.put("type", type);
                jsonObject.put("projectName", projectName);
                jsonObject.put("cloud_server_id", cloudServer.getId());
                jsonObject.put("ownerId", ownerId);// 虚拟机使用人ID
                jsonObject.put("remark", descBuffer.toString());
                amqpTemplate.convertAndSend("sync.shterm.queue", jsonObject);
                logger.info("send rabbitmq topic [sync.shterm.queue] ，message is ：{}", jsonObject.toJSONString());
            }
        } catch (Exception e) {
            logger.error("向堡垒机发送新增云主机的消息出错", e);
        }
    }


    /**
     * 向堡垒机发送删除虚拟机的消息
     * <p>
     * 发送数据到mq
     * </p>
     *
     * @param name       云主机名称
     * @param privateIps ip数据
     * @author lxy
     * @since 2021/5/15
     * @since 2023/8/25 modify by sxp 堡垒机相关的代码放在这里
     **/
    public void sendRemoveMsgToShterm(String name, String privateIps, String vendorType) {
        if (StringUtils.isEmpty(privateIps)) {
            return;
        }

        try {
            List<String> ipList = new ArrayList<>();

            if (CloudProvider.VMWARE.name().equals(vendorType)) {
                ipList = getVmwareIpList(privateIps);
            } else if (CloudProvider.SANGFOR.name().equals(vendorType)) {
                ipList = getSangforIpList(null, privateIps);
            } else {
                throw new RuntimeException("暂不支持云平台类型[" + vendorType + "]的IP地址解析");
            }

            for (String ip : ipList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name", name);
                jsonObject.put("privateIps", ip);
                amqpTemplate.convertAndSend("delete.shterm.queue", jsonObject);
                logger.info("send rabbitmq topic is [delete.shterm.queue]，message is ：{}", jsonObject.toJSONString());
            }
        } catch (Exception e) {
            logger.error("向堡垒机发送删除虚拟机的消息出错", e);
        }
    }


    /**
     * 向堡垒机发送更新虚拟机的消息
     * <p>
     * 向堡垒机发送修改密码消息
     * </p>
     *
     * @author: lxy
     * @Date 2021/5/16 19:32
     * @since 2023/8/25 modify by sxp 堡垒机相关的代码放在这里
     **/
    public void sendUpdateMsgToShterm(String newPassDes, CloudServer cloudServer) {
        String privateIps = cloudServer.getPrivateIps();
        if (StringUtils.isEmpty(privateIps)) {
            return;
        }

        try {
            String vendorType = cloudServer.getVendorType();

            List<String> ipList = new ArrayList<>();
            if (CloudProvider.VMWARE.name().equals(vendorType)) {
                ipList = getVmwareIpList(privateIps);
            } else if (CloudProvider.SANGFOR.name().equals(vendorType)) {
                ipList = getSangforIpList(cloudServer, privateIps);
            } else {
                ipList.add(cloudServer.getManagerIp());
            }

            String osCategory = cloudServer.getOsCategory();
            String username = "LINUX".equalsIgnoreCase(osCategory) ? "root" : "administrator";

            for (String ip : ipList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name", cloudServer.getName());
                jsonObject.put("oldName", cloudServer.getName());
                jsonObject.put("privateIps", ip);
                jsonObject.put("password", newPassDes);
                jsonObject.put("username", username);
                amqpTemplate.convertAndSend("update.shterm.queue", jsonObject);
                logger.info("send rabbitmq topic is [update.shterm.queue] ，message is ：{}", jsonObject.toJSONString());
            }
        } catch (Exception e) {
            logger.error("向堡垒机发送更新虚拟机的消息出错", e);
        }
    }


    /**
     * 向堡垒机发送更新虚拟机的消息
     * <p>
     * 向堡垒机发送修改密码消息
     * </p>
     *
     * @author: lxy
     * @Date 2021/5/16 19:32
     * @since 2023/8/25 modify by sxp 堡垒机相关的代码放在这里
     **/
    public void sendUpdateMsgToShterm(CloudServer cloudServer, String oldName) {
        String privateIps = cloudServer.getPrivateIps();
        if (StringUtils.isEmpty(privateIps)) {
            return;
        }

        try {
            String vendorType = cloudServer.getVendorType();

            List<String> ipList = new ArrayList<>();
            if (CloudProvider.VMWARE.name().equals(vendorType)) {
                ipList = getVmwareIpList(privateIps);
            } else if (CloudProvider.SANGFOR.name().equals(vendorType)) {
                ipList = getSangforIpList(cloudServer, privateIps);
            } else {
                ipList.add(cloudServer.getManagerIp());
            }

            for (String ip : ipList) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name", cloudServer.getName());
                jsonObject.put("oldName", oldName);
                jsonObject.put("privateIps", ip);
                amqpTemplate.convertAndSend("update.shterm.queue", jsonObject);
                logger.info("send rabbitmq topic is [update.shterm.queue] ，message is ：{}", jsonObject.toJSONString());
            }
        } catch (Exception e) {
            logger.error("向堡垒机发送更新虚拟机的消息出错", e);
        }
    }


    /**
     * vmware虚拟机解析privateIps
     *
     * @author sxp
     * @since 2023/8/25
     */
    public static List<String> getVmwareIpList(String privateIps) {
        //       [
        //        {
        //            "connected": false,
        //            "address": "169.254.155.93",
        //            "networkName": "DPortGroup-TEST-24",
        //            "mac": "00:50:56:a2:c3:03"
        //        }
        //        ]
        List<JSONObject> ips = JSON.parseArray(privateIps, JSONObject.class);
        List<String> ipList = ips.stream()
                .filter(json -> StringUtils.isNotEmpty(json.getString("address")))
                .map(json -> json.getString("address"))
                .collect(Collectors.toList());
        return ipList;
    }


    /**
     * 深信服虚拟机解析privateIps
     *
     * @author sxp
     * @since 2023/8/25
     */
    public static List<String> getSangforIpList(CloudServer cloudServer, String privateIps) {
        /*
         * {"net0":{"ip1":1},"net1":{"ip2":1}}
         * 或者
         * {"net0":{"ip1":1,"ip2":1}}
         */
        List<String> ipList = new ArrayList<>();

        if (FastjsonUtils.isJSONObject(privateIps)) {
            JSONObject json = JSON.parseObject(privateIps, JSONObject.class);
            Set<String> netcardSet = json.keySet();

            String value;
            Set<String> ipSet;
            JSONObject ipJson;
            Integer one = new Integer(1);

            for (String net : netcardSet) {
                value = json.getString(net);
                if (FastjsonUtils.isJSONObject(value)) {
                    ipJson = JSON.parseObject(value, JSONObject.class);
                    if (ipJson == null || ipJson.isEmpty()) {
                        continue;
                    }
                    ipSet = ipJson.keySet();
                    for (String ip : ipSet) {
                        if (Objects.equals(ipJson.getInteger(ip), one)) {
                            ipList.add(ip);
                        }
                    }
                }
            }
        }

        if (cloudServer != null && ipList.isEmpty()) {
            String ip = cloudServer.getManagerIp();
            if (StringUtils.isNotEmpty(ip)) {
                ipList.add(ip);
            }
        }
        return ipList;
    }


}
