package com.yizhi.application.course.util;

import java.io.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

public class CommandUtils {

    private static class StreamGobbler implements Runnable {
        private InputStream inputStream;
        private Consumer<String> consumer;

        public StreamGobbler(InputStream inputStream, Consumer<String> consumer) {
            this.inputStream = inputStream;
            this.consumer = consumer;
        }

        @Override
        public void run() {
            new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumer);
        }
    }

    public static void runtimeExec() throws IOException,InterruptedException {
        boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
        String homeDirectory = System.getProperty("user.home");
        Process process;
        if (isWindows) {
            process = Runtime.getRuntime()
                    .exec(String.format("cmd.exe /c dir %s", homeDirectory));
        } else {
            process = Runtime.getRuntime()
                    .exec(String.format("sh -c ls %s", homeDirectory));
        }
        StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println);
        Executors.newSingleThreadExecutor().submit(streamGobbler);
        int exitCode = process.waitFor();
        assert exitCode == 0;
    }

    public static void processBuilderExec() throws IOException,InterruptedException,ExecutionException,TimeoutException {
        // 多线程
        ExecutorService pool = Executors.newSingleThreadExecutor();
        ProcessBuilder processBuilder = new ProcessBuilder();

        boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
        ProcessBuilder builder = new ProcessBuilder();
        if (isWindows) {
            builder.command("cmd.exe", "/c", "dir");
        } else {
            builder.command("sh", "-c", "ls");
        }
        // 改变目录
        //builder.directory(new File(System.getProperty("user.home")));
        Process process = builder.start();
        ProcessReadTask task = new ProcessReadTask(process.getInputStream());
        Future<List<String>> future = pool.submit(task);
        List<String> result = future.get(5, TimeUnit.SECONDS);
        for (String s : result) {
            System.out.println(s);
        }
        pool.shutdown();
    }
    private static class ProcessReadTask implements Callable<List<String>> {

        private InputStream inputStream;

        public ProcessReadTask(InputStream inputStream) {
            this.inputStream = inputStream;
        }

        @Override
        public List<String> call() {
            return new BufferedReader(new InputStreamReader(inputStream))
                    .lines().collect(Collectors.toList());
        }
    }


    /**
     * 执行命令
     * @param parameter
     * @return
     * @throws IOException
     */
    public static String exec(String... parameter) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();

        ProcessBuilder processBuilder = new ProcessBuilder();
        //processBuilder.command("cmd.exe", "/c", "dir");
        //processBuilder.directory(new File("C:\\users"));
        processBuilder.command(parameter);
        Process process = processBuilder.start();
        // can also run the java file like this// processBuilder.command("java", "Hello");
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));) {
            String line;

            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }

            int exitCode = process.waitFor();
            System.out.println("Exited with error code : " + exitCode);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return stringBuilder.toString();
    }
}
