package com.ruoyi.cc.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.exec.*;

import java.io.ByteArrayOutputStream;
import java.util.Arrays;

@Slf4j
public class ShellUtil {
    /** 整串指令 -> 输出文本；超 30s 抛异常（仅内部兼容，业务勿再拼用户可控整串） */
    public static String exec(String wholeCmd) throws Exception {
        log.info("wholeCmd:{}", wholeCmd);
        CommandLine cl = CommandLine.parse(wholeCmd);
        return execute(cl);
    }

    /**
     * 固定 argv 执行（无 shell、不 parse 整串），用于 fingerprint 等可信命令。
     */
    public static String execArgs(String... args) throws Exception {
        if (args == null || args.length == 0 || args[0] == null || args[0].isEmpty()) {
            throw new IllegalArgumentException("empty command");
        }
        CommandLine cl = new CommandLine(args[0]);
        for (int i = 1; i < args.length; i++) {
            // false = do not handle quoting; pass literal argv
            cl.addArgument(args[i], false);
        }
        log.info("CommandLine: {}", Arrays.toString(cl.toStrings()));
        return execute(cl);
    }

    private static String execute(CommandLine cl) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayOutputStream err = new ByteArrayOutputStream();

        Executor exec = new DefaultExecutor();
        exec.setStreamHandler(new PumpStreamHandler(out, err));
        exec.setWatchdog(new ExecuteWatchdog(30_000));
        try {
            exec.execute(cl);
            return out.toString("UTF-8");
        } catch (Exception e) {
            int exitCode = -1;
            if (e instanceof ExecuteException) {
                exitCode = ((ExecuteException) e).getExitValue();
            }
            String stdout = out.toString("UTF-8");
            String stderr = err.toString("UTF-8");
            String msg = String.format("Command failed (exit=%d)%nstdout:%n%s%nstderr:%n%s",
                    exitCode, stdout, stderr);
            throw new CmdExecException(exitCode, msg);
        }
    }
}
