package services

import (
	"bytes"
	"fmt"
	"os"
	"path/filepath"
	"sync"
	"time"
	"xg_dba/api"
	"xg_dba/internal/global"
	"xg_dba/internal/models"
	"xg_dba/module/remote"

	"github.com/BurntSushi/toml"
)

func SetSystemInfo_service(connectInfo api.ConnectInfoRequest, saveFilePath string) error {
	//ssh连接服务器
	//执行命令
	//返回结果并存储到本地
	var wg sync.WaitGroup
	var mu sync.Mutex

	systemInfo := models.SystemMetaInfo{}

	commands := map[string]string{
		"OS Info":       "cat /etc/os-release",
		"CPU Info":      "lscpu",
		"Memory Info":   "free -h",
		"Disk Info":     "df -h",
		"Network Info":  "ip addr",
		"Disk Speed":    "dd if=/dev/zero of=/tmp/testfile bs=8K count=102400 oflag=direct; rm -f /tmp/testfile",
		"Network Speed": "ping -c 4 8.8.8.8",
	}

	for name, cmd := range commands {
		wg.Add(1)

		go func(name, cmd string) {
			defer wg.Done()

			// 每次执行命令都新建一个 SSH 客户端
			sshClient, err := remote.NewSSHClient(connectInfo.Id, connectInfo.Ssh.Username, connectInfo.Ssh.Password, connectInfo.Ssh.Host, connectInfo.Ssh.Port)
			if err != nil {
				global.Logger.Errorf("NewSSHClient failed for %s: %v", name, err)
				return
			}
			defer sshClient.Close()

			output, err := sshClient.RunCommand(cmd)
			if err != nil {
				global.Logger.Errorf("%s command failed: %v", name, err)
				return
			}

			mu.Lock()
			// 根据命令名称将输出赋值到结构体字段
			switch name {
			case "OS Info":
				systemInfo.Os = output
			case "CPU Info":
				systemInfo.Cpu = output
			case "Memory Info":
				systemInfo.Memory = output
			case "Disk Info":
				systemInfo.Disk = output
			case "Network Info":
				systemInfo.Network = output
			case "Disk Speed":
				systemInfo.DiskSpeed = output
			case "Network Speed":
				systemInfo.NetworkSpeed = output
			}
			mu.Unlock()

			fmt.Printf("--%s:\n%s\n", name, output)
		}(name, cmd)
	}

	wg.Wait()

	timestamp := time.Now().Format("20060102_150405")
	os.MkdirAll(filepath.Dir(saveFilePath), os.ModePerm)
	filePath := fmt.Sprintf("%sos_info_%s.toml", saveFilePath, timestamp)
	err := saveSystemMetaInfoToFile(systemInfo, filePath)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
	} else {
		fmt.Println("System meta info saved successfully")
	}
	return nil
}

// 保存系统环境信息到文件
func saveSystemMetaInfoToFile(info models.SystemMetaInfo, filePath string) error {
	var buffer bytes.Buffer
	encoder := toml.NewEncoder(&buffer)
	if err := encoder.Encode(info); err != nil {
		return fmt.Errorf("failed to encode system meta info to TOML: %v", err)
	}

	err := os.WriteFile(filePath, buffer.Bytes(), 0644)
	if err != nil {
		return fmt.Errorf("failed to write to file: %v", err)
	}
	return nil
}