/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.common.utils;

import com.crunii.micro.common.dto.SSHHost;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * @author 田平 create 2019年3月27日下午3:14:58
 */
public class ShellUtil {

	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	public static class CmdResult {
		private boolean success;
		private String result;
	}
	private static JSch jsch = new JSch();

	public static void main(String[] args) throws Exception {
		String host = "114.55.37.75";
		int port = 22;
		String username = "root";
		String password = "";
		SSHHost sshHost = new SSHHost();
		sshHost.setHost(host);
		sshHost.setPort(port);
		sshHost.setUsername(username);
		sshHost.setPassword(password);
		List<String> cmds = Arrays.asList("cd /root/micro-mini", "source /etc/profile;java -version");
		System.out.println(execCmds(sshHost, cmds));
	}

	/**
	 * <pre>如果需要制定执行路径，请第一条命令使用cd xxxpath</pre>
	 *
	 * @param sshHost
	 * @param cmds
	 * @return
	 */
	public static CmdResult execCmds(SSHHost sshHost, List<String> cmds) {
		String result = null;
		String errResult = null;
		if (cmds != null) {
			String execCmd = cmds.stream().collect(Collectors.joining(";"));
			ChannelExec channelExec = null;
			Session session = getSession(sshHost);
			InputStream input = null;
			InputStream errStream = null;
			try {
				channelExec = (ChannelExec) session.openChannel("exec");
				input = channelExec.getInputStream();
				errStream = channelExec.getErrStream();
				channelExec.setCommand(execCmd);
				channelExec.connect(sshHost.getConnectTimeout());
				result = StreamUtils.copyToString(input, StandardCharsets.UTF_8);
				errResult = StreamUtils.copyToString(errStream, StandardCharsets.UTF_8);
			} catch (Exception e) {
				throw new RuntimeException("Open channelExec error!", e);
			} finally {
				IOUtils.closeQuietly(input);
				IOUtils.closeQuietly(errStream);
				if (session != null) {
					session.disconnect();
				}
				if (channelExec != null) {
					channelExec.disconnect();
				}
			}
		}
		CmdResult cmdResult = new CmdResult();
		if (StringUtils.hasText(errResult)) {
			cmdResult.setSuccess(false);
			cmdResult.setResult(errResult);
		} else {
			cmdResult.setSuccess(true);
			cmdResult.setResult(result);
		}
		return cmdResult;
	}

	/**
	 * <pre>注意关闭session</pre>
	 *
	 * @param sshHost
	 * @return
	 */
	public static Session getSession(SSHHost sshHost) {
		try {
			Session session = jsch.getSession(sshHost.getUsername(), sshHost.getHost(), sshHost.getPort());// 根据用户名，主机ip和端口获取一个Session对象
			session.setPassword(sshHost.getPassword()); // 设置密码
			Properties config = new Properties();
			config.put("StrictHostKeyChecking", "no");
			session.setConfig(config);// 为Session对象设置properties
			session.setTimeout(sshHost.getSoTimeout());// 设置超时
			session.connect(sshHost.getConnectTimeout());// 通过Session建立连接
			return session;
		} catch (Exception e) {
			throw new RuntimeException("getSession error!", e);
		}
	}

}
