package sshx

import (
	"encoding/json"
	"fmt"
	"gadmin/internal/admin/forms"
	"net"
	"os"
	"strconv"
	"time"

	"github.com/sirupsen/logrus"
	"golang.org/x/crypto/ssh"
)

type Message struct {
	Code int    `json:"code"`
	Err  string `json:"err"`
	Data any    `json:"data"`
}

type Version struct {
	Err  string   `json:"error"`
	Data []string `json:"data"`
}

func Session(user, password, host string, port int) (sshSession *ssh.Session, err error) { //参数: 远程服务器用户名, 密码, ip, 端口
	sshClient, err := connector(user, password, host, port) //连接ssh
	if err != nil {
		return
	}

	sshSession, err = sshClient.NewSession()
	return
}

func connector(user, password, host string, port int) (sshClient *ssh.Client, err error) {
	auth := make([]ssh.AuthMethod, 0)
	auth = append(auth, ssh.Password(password))

	clientConfig := &ssh.ClientConfig{
		User:    user,
		Auth:    auth,
		Timeout: 30 * time.Second,
		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
			return nil
		},
	}

	addr := host + ":" + strconv.Itoa(port)
	sshClient, err = ssh.Dial("tcp", addr, clientConfig) //连接ssh
	return
}

// ReleaseVersion 发版
func ReleaseVersion(v string, i int) (err error) {
	session, err := Session(os.Getenv("LOGIN_SSH_USER"), os.Getenv("LOGIN_SSH_PASSWORD"), os.Getenv("LOGIN_SSH_HOST"), 22)
	if err != nil {
		return
	}
	defer session.Close()

	session.Stdout = os.Stdout
	session.Stderr = os.Stderr
	session.Stdin = os.Stdin
	cmd := fmt.Sprintf("cd %v && sudo ./version -op='update' -p='%v' -v='%v' -i='%v'", os.Getenv("LOGIN_RELEASE_PATH"), os.Getenv("LOGIN_RELEASE_PATH"), v, i)
	logrus.Warnf("ReleaseVersion cmd:%+v ", cmd)
	return session.Run(cmd)
}

// VersionList 版本列表
func VersionList() (ds []string, err error) {
	session, err := Session(os.Getenv("LOGIN_SSH_USER"), os.Getenv("LOGIN_SSH_PASSWORD"), os.Getenv("LOGIN_SSH_HOST"), 22)
	if err != nil {
		return
	}
	defer session.Close()

	cmd := fmt.Sprintf("cd %v && sudo ./version -op='scan' ", os.Getenv("LOGIN_RELEASE_PATH"))

	b, err := session.Output(cmd)
	if err != nil {
		return
	}
	var ver Version
	err = json.Unmarshal(b, &ver)
	if err != nil {
		return
	}
	ds = ver.Data
	logrus.Warnf("VersionList cmd:%+v b:%+v  ds:%+v  err:%+v", cmd, string(b), ds, err)
	return
}

// GetVersionIndex 版本列表
func GetVersionIndex(req forms.GetVersionIndexReq) (res *Message, err error) {
	session, err := Session(os.Getenv("LOGIN_SSH_USER"), os.Getenv("LOGIN_SSH_PASSWORD"), os.Getenv("LOGIN_SSH_HOST"), 22)
	if err != nil {
		return
	}
	defer session.Close()

	cmd := fmt.Sprintf("cd %v && sudo ./version -op='index' -p='%v' -v='%v'", os.Getenv("LOGIN_RELEASE_PATH"), os.Getenv("LOGIN_RELEASE_PATH"), req.Version)

	b, err := session.Output(cmd)
	if err != nil {
		return
	}

	logrus.Warnf("GetVersionIndex cmd:%+v b:%+v", cmd, string(b))

	err = json.Unmarshal(b, &res)
	return
}
