package com.platform2easy.genesis.lib;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

public class BashExecutor {

    public static Result run(String command, long timeoutMs) {
        StringBuilder output = new StringBuilder();
        int exitCode = -1;
        boolean timedOut = false;

        try {
            ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", command);
            processBuilder.redirectErrorStream(true);
            Process process = processBuilder.start();
            
            // Read output in a separate thread
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            Thread readerThread = new Thread(() -> {
                try { 
                    String line;
                    while ((line = reader.readLine()) != null) {
                        output.append(line).append("\n");
                    }
                } catch (IOException e) {
                    output.append("Error reading output: ").append(e.getMessage());
                }
            });
            readerThread.start();

            // Wait for the process to complete or timeout
            if (!process.waitFor(timeoutMs, TimeUnit.MILLISECONDS)) {
                // Timeout occurred
                process.destroyForcibly();
                timedOut = true;
                output.append("\nCommand timed out after ").append(timeoutMs).append("ms");
            }

            // Wait for reader thread to finish
            readerThread.join(1000);
            
            if (!timedOut) {
                exitCode = process.exitValue();
            }

        } catch (IOException | InterruptedException e) {
            output.append("Error executing command: ").append(e.getMessage());
        }

        return new Result(output.toString().trim(), exitCode, timedOut);
    }

    /**
     * Result container for command execution.
     */
    public static class Result {
        private final String output;
        private final int exitCode;
        private final boolean timedOut;

        public Result(String output, int exitCode, boolean timedOut) {
            this.output = output;
            this.exitCode = exitCode;
            this.timedOut = timedOut;
        }

        public String getOutput() {
            return output;
        }

        public int getExitCode() {
            return exitCode;
        }

        public boolean isTimedOut() {
            return timedOut;
        }
    }
}
