package com.dashitech.utils;

import java.io.*;
import java.util.Locale;
import java.util.UUID;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 执行系统命令，并返回完成信息
 */
public class SystemCmdExecutor {
	private static Log log = LogFactory.getLog(SystemCmdExecutor.class);

	

	/**
	 * 根据传来的命令执行，返回命令执行完后的信息
	 * 
	 * @param command
	 *            命令
	 * @param fileRoot
	 *            命令所在目录
	 * @param charset
	 *            返回流字符编码
	 * @return 完成信息，根据结果处理报错
	 * @throws IOException
	 *             如果执行报错，需要抓取错误自主处理
	 */
	public static String execute(String command, String fileRoot, String charset) {
		class ProcessStream extends Thread {
			private InputStream is;
			private String type;
			private String charset;
			private String info;
			private String error;
			ProcessStream(InputStream is, String type,String charset) {
				this.is = is;
				this.type = type;
				this.charset = charset;
			}
			public void run() {
				try {
					InputStreamReader isr = new InputStreamReader(is, charset);
					BufferedReader br = new BufferedReader(isr);
					String line = null;
					while ((line = br.readLine()) != null) {
						if (type.equals("ERROR")) {
							error += line;
							log.error(line);
						}else if (type.equals("INFO")) {
							info += line;
							log.info(line);
						}
					}
					is.close();
					isr.close();
					br.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
			public String getInfo() {
				return info;
			}
			public String getError() {
				return error;
			}
		}
		
		String result = "";
		Runtime rt = Runtime.getRuntime();
		Process p = null;
		try {
			if (fileRoot == null) {
				p = rt.exec(command);
			} else {
				p = rt.exec(command, null, new File(fileRoot));
			}
			
			

			ProcessStream errorStream = new ProcessStream(p.getErrorStream(), "ERROR",charset);
			ProcessStream infoStream = new ProcessStream(p.getInputStream(), "INFO",charset);
			errorStream.start();
			infoStream.start();

			int code = p.waitFor();
			//0 正常，其他错误
			if(code == 0) {
				result = infoStream.getInfo();
			}else {
				result = errorStream.getError();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("执行系统命令错误！" + command + ";" + e.getMessage());
		} finally {
			try {
				if (p != null) {
					p.getOutputStream().close();
					p.destroy();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * 返回字符使用GBK，使用命令路径
	 * 
	 * @throws IOException
	 */
	public static String execute(String command, String fileRoot) {
		return execute(command, fileRoot, "GBK");
	}

	/**
	 * 返回字符使用GBK，使用系统命令不需要命令目录
	 * 
	 * @throws IOException
	 */
	public static String execute(String command) {
		return execute(command, null, "GBK");
	}

	public static void main(String[] args) throws IOException {
		String cmd = "D:/G/workbench/myeclipse9_workplace/11cms/src/";
		String cmd2 = "nginnxReload.bat";
		// String cmd = "D:/E/software/environment/nginx-1.8.0/";
		// String cmd2 = "nginx.exe -s reload";
		// String cmd =
		// "D:/G/workbench/myeclipse9_workplace/11cms/src/nginnxReload.bat";
		// String cmd2 = "";
		// System.out.println(SystemCmdExecutor.execute(cmd + cmd2));
		System.out.println(SystemCmdExecutor.execute(cmd + cmd2, cmd));

	}

	public static String executeLinuxCmd(String cmd) {
		System.out.println("执行命令[ " + cmd + "]");
		Runtime run = Runtime.getRuntime();
		try {
			Process process = run.exec(cmd);
			String line;
			BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			StringBuffer out = new StringBuffer();
			while ((line = stdoutReader.readLine()) != null ) {
				out.append(line);
			}
			try {
				process.waitFor();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			process.destroy();
			return out.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 修改系统时间
	 * yyyy-MM-dd HH:mm:ss
	 * @param dataStr_   2017-11-11   yyyy-MM-dd
	 * @param timeStr_   11:11:11     HH:mm:ss
	 */
	public static void updateSysDateTime(String dataStr_,String timeStr_){
		try {
			String osName = System.getProperty("os.name");
			// Window 系统
			if (osName.matches("^(?i)Windows.*$")) {
				String cmd;
				// 格式：yyyy-MM-dd
				cmd = " cmd /c date " + dataStr_;
				Runtime.getRuntime().exec(cmd);
				// 格式 HH:mm:ss
				cmd = " cmd /c time " + timeStr_;
				String res = runAndResult(cmd);
				System.out.println("windows 时间修改" + res);
			} else if (osName.matches("^(?i)Linux.*$")) {
				// Linux 系统 格式：yyyy-MM-dd HH:mm:ss   date -s "2017-11-11 11:11:11"
				String datash = PropertiesUtil.getProperty("date.sh");
				FileWriter excutefw = new FileWriter(datash+"updateSysTime.sh");
				BufferedWriter excutebw=new BufferedWriter(excutefw);
				excutebw.write("date -s \"" + dataStr_ +" "+ timeStr_ +"\"\r\n");
				excutebw.close();
				excutefw.close();
				String cmd_date ="sh "+datash+"updateSysTime.sh";
				String res = runAndResult(cmd_date);
				System.out.println("cmd :" + cmd_date + " date :" + dataStr_ +" time :" + timeStr_);
				System.out.println("linux 时间修改" + res);
			} else {
				System.out.println("操作系统无法识别");
			}
		} catch (Exception e) {
			e.getMessage();
		}
	}

	/**
	 * 执行 脚本命令  关心结果
	 * @param cmd
	 * @return
	 */
	public static String runAndResult(String cmd) throws Exception{
		StringBuilder sb = new StringBuilder();
		BufferedReader br = null;
		boolean execFlag = true;

		String uuid = UUID.randomUUID().toString().replace("-","");
		String tempFileName = "./temp" + uuid +".sh";
		try {
			String osName = System.getProperty("os.name").toUpperCase(Locale.ENGLISH);

			if (osName.matches("^(?i)LINUX.*$") || osName.contains("MAC")) {
				FileWriter excutefw = new FileWriter(tempFileName);
				BufferedWriter excutebw=new BufferedWriter(excutefw);
				excutebw.write(cmd + "\n");
				excutebw.close();
				excutefw.close();
				String command ="bash " + tempFileName;

				Process p = Runtime.getRuntime().exec(command);
				p.waitFor();

				br = new BufferedReader(new InputStreamReader(p.getInputStream()));
				String line;
				while ((line = br.readLine()) != null) {
					//sb.append("<br/>");
					sb.append(System.lineSeparator());
					sb.append(line);
				}
				br.close();

				br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
				while ((line = br.readLine()) != null) {
					//sb.append("<br/>");
					sb.append(System.lineSeparator());
					sb.append(line);
					if (line.length() > 0){
						execFlag = false;
					}
				}
				br.close();

				if (execFlag){
					System.out.println("exec [ {"+cmd+"} ]  OK , result : [ {"+sb.toString()+"} ]");
				}else {
					throw new RuntimeException(sb.toString());
				}
			}else {
				throw new RuntimeException("不支持的操作系统类型");
			}
		} catch (Exception e) {
			System.out.println("exec [ {"+cmd+"} ]  fail : {"+e.getMessage()+"}");
			throw e;
		}finally {
			if (br != null){
				br.close();
			}
			File excutefw = new File(tempFileName);
			excutefw.delete();
		}
		return sb.toString();
	}

}