package utils

import (
	"bytes"
	"context"
	"os/exec"
	"pbx-api-gin/pkg/lfshook"
	"time"
)

// ExecCmdAsync 执行指定命令
func ExecCmdAsync(cmdName string, arg ...string) (stdOut, errOut string, err error) {
	cmd := exec.Command(cmdName, arg...)
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err = cmd.Run()
	if err != nil {
		lfshook.NewLogger().Errorf("cmd.Run(%s) failed with %s\n", cmdName, err)
	}
	outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
	if len(outStr) > 0 {
		lfshook.NewLogger().Debugf("cmd.Run(%s) %s", cmdName, outStr)
	}
	if len(errStr) > 0 {
		lfshook.NewLogger().Errorf("cmd.Run(%s)%s", cmdName, errStr)
	}
	return outStr, errStr, err
}

// ExecCmd 执行指定命令
func ExecCmd(cmdName string, arg ...string) (stdOut, errOut string, err error) {
	cmd := exec.Command(cmdName, arg...)
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	err = cmd.Start()
	if err != nil {
		lfshook.NewLogger().Error(err)
		return "", "", err
	}

	go func() {
		err = cmd.Wait()
		if err != nil {
			lfshook.NewLogger().Errorf("cmd.Wait(%s) %s\n", cmdName, err)
		} else {
			lfshook.NewLogger().Infof("cmd.Wait(%s)\n", cmdName)
		}
		cancel()
	}()

	select {
	case <-ctx.Done():
	}

	outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
	if len(outStr) > 0 {
		lfshook.NewLogger().Debugf("cmd.Start(%s) %s", cmdName, outStr)
	}
	if len(errStr) > 0 {
		lfshook.NewLogger().Errorf("cmd.Start(%s)%s", cmdName, errStr)
	}
	return outStr, errStr, err
}
