package com.bocloud.ims.service.utils;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.encrypt.AESEncrptor;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.ssh.SshClient;
import com.bocloud.ims.entity.resource.ServerConfig;
import org.apache.commons.net.telnet.TelnetClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class ServerHelper {
    private static final Logger logger = LoggerFactory.getLogger(ServerHelper.class);

    /**
     * @since 2018-04-17 modify by sxp 修正获取不到cpuVendor,cpuMode,cpuAmount的bug
     * @since 2018-08-09 modify by lkx007 修正biosDate的bug, ifconfig改善为ip addr
     */
    public static BocloudResult fromSSH(String username, String password, String ip, Integer port, Logger logger) {
        final String oldPassword = password;
        try {
            AESEncrptor aesEncrptor = new AESEncrptor();
            password = aesEncrptor.decrypt(password, null);
            if (password == null) {
            	password = oldPassword;
            }
        } catch (Exception ignored) {
            password = oldPassword;
        }
        SshClient ssh = null;
        if (null == port) {
            ssh = new SshClient(ip, username, password);
        } else {
            ssh = new SshClient(ip, username, password, port);
        }

        try {
            if (!ssh.connect()) {
                logger.warn("Server username or password error!");
                return new BocloudResult(false, "服务器地址端口、用户账号或密码错误");
            }
            StringBuffer commandBuffer = new StringBuffer();
            commandBuffer.append("dmidecode | grep UUID | awk '{print \"uuid:\"$2}';")
                    .append("dmidecode -t memory | grep 'Type: D' | head -1 | awk '{print \"memoryMode:\"$2}';")
                    .append("dmidecode | grep -i -A6 'Bios Information' | grep -iw version | awk '{print \"biosVersion:\"$2}';")
                    .append("dmidecode | grep -i -A6 'Bios Information' | grep -iw vendor | awk -F ': ' '{print \"biosVendor:\"$2}';")
                    .append("dmidecode | grep -i -A6 'Bios Information' | grep -iw 'date' | awk -F ': ' '{print $2}' | awk -F '/' '{print \"biosDate:\"$3\"-\"$1\"-\"$2}'|tr -d \" \";")
                    .append("cat /proc/meminfo | grep MemTotal | awk '{print $2/1024/1024}'| awk -F . '{if(substr($2,1,1)>5)\"memoryCapacity:\"$1+1;print \"memoryCapacity:\"$1}';")
                    .append("cat /proc/cpuinfo |grep 'processor'|wc -l|awk '{print \"cpuAmount:\"$1}';")
                    .append("cat /proc/cpuinfo |grep 'vendor_id'|head -1|awk '{print \"cpuVendor:\"$3}';")
                    .append("cat /proc/cpuinfo |grep 'cpu MHz'|head -1|awk '{print \"cpuHz:\"$4}';")
                    .append("cat /proc/cpuinfo |grep 'model name'|head -1|awk '{print \"cpuMode:\"$4\" \"$5\" \"$6\" \"$7\" \"$8\" \"$9}';")
                    .append("cat /proc/cpuinfo | grep vmx |head -1| awk '{if($1~/a\\s*b/)\"virtualized:false\";print \"virtualized:true\"}';")
                    .append("cat /proc/cpuinfo | grep svm |head -1| awk '{if($1~/a\\s*b/)\"virtualized:false\";print \"virtualized:true\"}';")
                    .append("fdisk -l | grep -i 'disk /dev/sda' | awk '{print $3}' | awk -F . '{if(substr($2,1,1)>5)\"diskCapacity:\"$1+1;print \"diskCapacity:\"$1}';")
                    .append("cat /etc/os-release | grep -iw pretty_name | awk -F = '{print $2}' | awk -F'\"' '{print \"osName :\"$2}';")
                    .append("cat /etc/os-release | grep -iw version | awk -F = '{print $2}' | awk -F '\"' '{print \"osVersion:\"$2\" \"$3}';")
                    .append("uname -a|awk '{print \"kernelVersion:\"$3}';")
                    .append("cat /etc/ssh/ssh_config | grep -iw port | awk '{print \"managerPort:\"$3}';")
                    .append("ip addr|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|cut -d \"/\" -f 1 | awk '{print \"managerIp:\"$1}';");
            String result = ssh.executeWithResult(commandBuffer.toString());
            // cpuHz从double转成long
            JSONObject object = ClassHelper.getJson(result);
            long cpuHz = (long) object.getDoubleValue("cpuHz");
            object.put("cpuHz", cpuHz);
            ServerConfig serverConfig = JSONObject.parseObject(object.toString(), ServerConfig.class);
            if (port != null) {
                serverConfig.setSshPort(port);
            }
            return new BocloudResult(true, serverConfig, "获取服务器数据成功");
        } catch (Exception e) {
            logger.error("Connect ssh fail:", e);
            return new BocloudResult(false, "服务器地址端口、用户账号或密码错误");
        } finally {
            ssh.close();
        }
    }

    /**
     * 测试能否ssh以及ssh的用户名密码端口号是否正确
     * 
     * @param username
     * @param password
     * @param ip
     * @param port
     * @return
     */
    public static BocloudResult fromSSH(String username, String password, String ip, Integer port) {
        final String oldPassword = password;
        try {
            AESEncrptor aesEncrptor = new AESEncrptor();
            password = aesEncrptor.decrypt(password, null);
            if (password == null) {
            	password = oldPassword;
            }
        } catch (Exception ignored) {
            password = oldPassword;
        }
        SshClient ssh = null;
        if (null == port) {
            ssh = new SshClient(ip, username, password);
        } else {
            ssh = new SshClient(ip, username, password, port);
        }
        try {
            if (!ssh.connect()) {
                return new BocloudResult(false, "服务器地址端口、用户账号或密码错误");
            }
            return new BocloudResult(true, "服务器地址端口、用户账号或密码正确");
        } catch (Exception e) {
            return new BocloudResult(false, "服务器地址端口、用户账号或密码错误");
        } finally {
            ssh.close();
        }
    }

    /**
     * 使用checkCommand来检查机器信息
     * 
     * @param username
     * @param password
     * @param ip
     * @param port
     * @param checkCommand
     * @return
     */
    public static boolean fromSSH(String username, String password, String ip, Integer port, String checkCommand) {
        final String oldPassword = password;
        try {
            AESEncrptor aesEncrptor = new AESEncrptor();
            password = aesEncrptor.decrypt(password, null);
            if (password == null) {
            	password = oldPassword;
            }
        } catch (Exception ignored) {
            password = oldPassword;
        }
        SshClient ssh = null;
        if (null == port) {
            ssh = new SshClient(ip, username, password);
        } else {
            ssh = new SshClient(ip, username, password, port);
        }
        try {
            if (!ssh.connect()) {
                return false;
            }
            return ssh.execute(checkCommand);
        } catch (Exception e) {
            return false;
        } finally {
            ssh.close();
        }
    }

    /**
     * 使用ssh执行command命令
     * 
     * @param username
     * @param password
     * @param ip
     * @param port
     * @param command
     * @return
     */
    public static BocloudResult executeBySSH(String username, String password, String ip, Integer port,
            String command) {
        final String oldPassword = password;
        try {
            AESEncrptor aesEncrptor = new AESEncrptor();
            password = aesEncrptor.decrypt(password, null);
            if (password == null) {
            	password = oldPassword;
            }
        } catch (Exception ignored) {
            password = oldPassword;
        }
        SshClient ssh = null;
        if (null == port) {
            ssh = new SshClient(ip, username, password);
        } else {
            ssh = new SshClient(ip, username, password, port);
        }
        try {
            if (!ssh.connect()) {
                return new BocloudResult(false, "连接失败");
            }
            return new BocloudResult(true, ssh.executeWithResult(command), "执行成功");
        } catch (Exception e) {
            logger.error("执行异常:", e);
            return new BocloudResult(false, "执行异常");
        } finally {
            ssh.close();
        }
    }

    public static BocloudResult fromTelnet(String username, String password, String ip, Integer port, Logger logger) {
        final String oldPassword = password;
        try {
            AESEncrptor aesEncrptor = new AESEncrptor();
            password = aesEncrptor.decrypt(password, null);
            if (password == null) {
            	password = oldPassword;
            }
        } catch (Exception ignored) {
            password = oldPassword;
        }
        // 指明Telnet终端类型，否则会返回来的数据中文会乱码
        TelnetClient client = new TelnetClient("vt200");
        try {
            client.connect(ip, port);
            if (!client.isConnected()) {
                return new BocloudResult(false, "服务器地址、端口或Telnet服务未启动");
            }
            return new BocloudResult(true, "连接成功");
        } catch (Exception e) {
            logger.error("Connect telnet fail:", e);
            return new BocloudResult(false, "服务器地址、端口或Telnet服务未启动");
        } finally {
            try {
                client.disconnect();
            } catch (IOException e) {
                logger.error("close telnet error:", e);
            }
        }
    }
}
