package remote

import (
	"bytes"
	"context"
	"os"
	"strings"
	"time"
	"xg_auto_deploy/internal/global"
	"xg_auto_deploy/internal/models"

	"golang.org/x/crypto/ssh"
)

func SingleCmd(nodeConfig *models.ServerNodeConfig, cmd string) (string, error) {

	// 作为客户端连接SSH服务器
	client, err := ssh.Dial("tcp", nodeConfig.IpPort, nodeConfig.SSHClient)
	if err != nil {
		global.Logs.Fatal("ssh服务器失败 (Failed to dial): ", err)
		os.Exit(0)
	}
	defer client.Close()

	// 创建会话
	session, err := client.NewSession()
	if err != nil {
		global.Logs.Fatal("Failed to create session: ", err)
		os.Exit(0)
	}
	defer session.Close()

	// 设置会话标准输出,运行命令
	var b bytes.Buffer
	session.Stdout = &b
	//global.Log.Info("执行命令:", cmd)
	if err := session.Run(cmd); err != nil {
		// log.Errorf("Failed to run: " + cmd)
		// log.Errorf("命令运行失败: %s", err)
		return b.String(), err
	}

	//fmt.Println(b.String())
	return b.String(), nil
}

func SingleCmdTime(nodeConfig *models.ServerNodeConfig, cmd string) (string, error) {

	// 替换为你的远程服务器的 IP 地址和端口
	client, err := ssh.Dial("tcp", nodeConfig.IpPort, nodeConfig.SSHClient)
	if err != nil {
		global.Logs.Fatalf("Failed to dial: %s", err)
	}
	defer client.Close()

	// 创建新会话
	session, err := client.NewSession()
	if err != nil {
		global.Logs.Fatalf("Failed to create session: %s", err)
	}
	defer session.Close()

	// 捕获标准输出和标准错误输出
	var stdoutBuilder, stderrBuilder strings.Builder
	session.Stdout = &stdoutBuilder
	session.Stderr = &stderrBuilder

	// 设置超时
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// 创建一个通道来接收命令执行结果
	done := make(chan error, 1)
	go func() {
		// 执行远程命令
		err := session.Run(cmd) // 替换为你要执行的命令
		done <- err
	}()

	// 等待命令执行结果或者超时
	select {
	case <-ctx.Done():
		global.Logs.Println("Command timed out")
		return "执行超时", nil
	case err := <-done:
		if err != nil {
			global.Logs.Printf("Failed to run: %s", err)
			global.Logs.Printf("Stderr: %s", stderrBuilder.String())
			return "", err
		} else {
			global.Logs.Println("Command executed successfully")
			global.Logs.Printf("Stdout: %s", stdoutBuilder.String())
			return "执行完毕", nil
		}
	}

}