package com.fdkankan.ucenter.common.utils;

import cn.hutool.core.io.file.FileReader;
import com.alibaba.fastjson.JSONObject;
import com.fdkankan.ucenter.common.constants.NacosProperty;
import com.fdkankan.ucenter.common.constants.ShellCmd;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;

@Slf4j
public class ShellUtil {

    /**
     * 执行系统命令, 返回执行结果
     * @param cmd 需要执行的命令
     */
    public static void execCmd(String cmd) {
        StringBuilder result = new StringBuilder();

        Process process = null;
        BufferedReader bufrIn = null;
        BufferedReader bufrError = null;
        long startTime = System.currentTimeMillis();

        try {
            // 执行命令, 返回一个子进程对象（命令在子进程中执行）
            log.info("执行cmd:{}",cmd);
            process = Runtime.getRuntime().exec(cmd);
            // 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
            //处理InputStream的线程
            threadRun(process);
            // 方法阻塞, 等待命令执行完成（成功会返回0）
            process.waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            closeStream(bufrIn);
            closeStream(bufrError);
            // 销毁子进程
            if (process != null) {
                process.destroy();
            }
        }
        // 返回执行结果
        log.info("执行cmd:{},结果:{},耗时:{}", cmd,result.toString(),System.currentTimeMillis() -startTime);
    }

    private static void threadRun(Process process) {
        new Thread() {
            @Override
            public void run() {
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = null;
                try {
                    while((line = in.readLine()) != null) {
                       log.debug("output: " + line);
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                finally {
                    try {
                        in.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String line = null;
                try {
                    while((line = err.readLine()) != null) {
                        log.debug("err: " + line);
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
                finally {
                    try {
                        err.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    private static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * oss文件上传命令 bash /opt/ossutil/fyun-upload.sh {bucket} {srcPath} {destPath} {fyunType} {opType}
     * opType: file or folder
     *  //@param bucket     桶名
     * @param srcPath    源文件路径
     * @param destPath   目标文件路径
     *  //@param fyunType   oss or aws
     */
    public static void yunUpload(String srcPath,String destPath){
        String opType = srcPath.contains(".")? "file":"folder" ;
        String cmd = String.format(ShellCmd.FYUN_UPLOAD, NacosProperty.bucket,srcPath,destPath,NacosProperty.uploadType,opType);
        execCmd(cmd);
    }
    public static void yunDownload(String srcPath,String destPath){
        String opType = srcPath.contains(".")? "file":"folder" ;
        String cmd = String.format(ShellCmd.FYUN_DOWN,NacosProperty.bucket,srcPath,destPath,NacosProperty.uploadType,opType);
        execCmd(cmd);
    }

}
