package cmd

import (
	"agent-wdd/cmd/beans"
	"agent-wdd/host_info"
	"agent-wdd/log"
	"agent-wdd/op"
	"agent-wdd/utils"
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"

	"github.com/spf13/cobra"
)

var (
	ubuntuCommonTools = []string{
		"apt-utils",
		"iputils-ping",
		"net-tools",
		"dnsutils",
		"lsof",
		"curl",
		"wget",
		"mtr-tiny",
		"vim",
		"htop",
		"lrzsz",
	}
	centosCommonTools = []string{
		"deltarpm",
		"net-tools",
		"iputils",
		"bind-utils",
		"lsof",
		"curl",
		"wget",
		"vim",
		"mtr",
		"htop",
	}

	// https://download.docker.com/linux/static/stable/ 官方下载地址
	// https://github.com/docker/compose/releases?page=8&tags=2.18.0

	// https://cdn.dl.k8s.io/release/v1.30.14/bin/linux/amd64/kubectl

	dockerLocalInstallPath        = "/root/wdd/docker-amd64-20.10.15.tgz"           // 本地安装docker的文件路径
	dockerComposeLocalInstallPath = "/root/wdd/docker-compose-v2.18.0-linux-amd64"  // 本地安装docker compose的文件路径
	harborLocalInstallPath        = "/root/wdd/harbor-offline-installer-v2.9.0.tgz" // 本地安装harbor的文件路径
)

func init() {
	switch runtime.GOARCH {
	case "amd64":
		dockerLocalInstallPath = "/root/wdd/docker-amd64-20.10.15.tgz"                 // 本地安装docker的文件路径
		dockerComposeLocalInstallPath = "/root/wdd/docker-compose-v2.18.0-linux-amd64" // 本地安装docker compose的文件路径
		harborLocalInstallPath = "/root/wdd/harbor-offline-installer-v2.9.0.tgz"       // 本地安装harbor的文件路径
	case "arm64":
		dockerLocalInstallPath = "/root/wdd/docker-arm64-20.10.15.tgz"                 // 本地安装docker的文件路径
		dockerComposeLocalInstallPath = "/root/wdd/docker-compose-v2.18.0-linux-arm64" // 本地安装docker compose的文件路径
		harborLocalInstallPath = "/root/wdd/harbor-offline-installer-v2.9.0-arm64.tgz" // 本地安装harbor的文件路径
	}
}

// 添加base子命令
func addBaseSubcommands(cmd *cobra.Command) {
	// 1.1 docker
	dockerCmd := &cobra.Command{
		Use:   "docker",
		Short: "Docker相关操作",
	}
	addDockerSubcommands(dockerCmd)

	// 1.2 dockercompose
	dockerComposeCmd := &cobra.Command{
		Use:   "dockercompose",
		Short: "Docker Compose相关操作",
	}
	addDockerComposeSubcommands(dockerComposeCmd)

	// 其他base子命令...
	swapCmd := &cobra.Command{
		Use:   "swap",
		Short: "关闭系统的Swap",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Swap 关闭!")
			// 实现这个函数，能够关闭centos或者ubuntu系统的swap

			// 备份文件存在，pass
			if !utils.FileExistAndNotNull("/etc/fstab_back_wdd_swap") {
				utils.AppendOverwriteContentToFile(
					"/etc/fstab",
					"/etc/fstab_back_wdd_swap",
				)
			}
			// 执行关闭操作
			op.SingleLineCommandExecutor([]string{
				"swapoff",
				"-a",
			})

			op.SingleLineCommandExecutor([]string{
				"sed",
				"-i",
				"/swap/d",
				"/etc/fstab",
			})

			log.Info("Swap 关闭成功!")
		},
	}

	selinuxCmd := &cobra.Command{
		Use:   "selinux",
		Short: "关闭selinux",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Selinux 关闭!")

			// 如果configCache的OS为空，则收集OS信息
			if host_info.ConfigCache.Agent.OS.Hostname == "" {
				log.Warning("ConfigCache OS is nil")
				host_info.ConfigCache.Agent.OS.Gather()
				host_info.ConfigCache.Agent.OS.SaveConfig()
			}

			os := host_info.ConfigCache.Agent.OS
			if os.IsUbuntuType {
				log.Info("Ubuntu 系统，跳过关闭selinux！")
				return
			} else {
				op.SingleLineCommandExecutor([]string{
					"setenforce",
					"0",
				})

				// 备份一下/etc/selinux/config
				if !utils.FileExistAndNotNull("/etc/selinux/config_back_wdd_selinux") {
					utils.AppendOverwriteContentToFile(
						"/etc/selinux/config",
						"/etc/selinux/config_back_wdd_selinux",
					)
				}

				// 持久化关闭selinux
				utils.FindAndDeleteContentInFile("SELINUX=enforcing", "/etc/selinux/config")
				utils.FindAndDeleteContentInFile("SELINUX=permissive", "/etc/selinux/config")
				utils.FindAndDeleteContentInFile("SELINUX=disabled", "/etc/selinux/config")
				utils.AppendContentToFile("SELINUX=disabled", "/etc/selinux/config")
			}

			log.Info("Selinux 关闭成功!")
		},
	}

	firewallCmd := &cobra.Command{
		Use:   "firewall",
		Short: "关闭防火墙",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Firewall 关闭!")

			// 调用systemd关闭firewalld
			op.SystemdDown("firewalld")
			op.SystemdDisable("firewalld")
			// 调用systemd关闭ufw
			op.SystemdDown("ufw")
			op.SystemdDisable("ufw")

			// 清空路由表
			log.Info("清空路由表...")

			commandExecutor := [][]string{
				{
					"iptables",
					"-F",
				},
				{
					"iptables",
					"-t",
					"nat",
					"-F",
				},
				{
					"iptables",
					"-t",
					"mangle",
					"-F",
				},
				{
					"iptables",
					"-t",
					"raw",
					"-F",
				},
				{
					"ip6tables",
					"-F",
				},
				{
					"ip6tables",
					"-t",
					"nat",
					"-F",
				},
				{
					"ip6tables",
					"-t",
					"mangle",
					"-F",
				},
				{
					"ip6tables",
					"-t",
					"raw",
					"-F",
				},
			}

			for _, command := range commandExecutor {
				op.SingleLineCommandExecutor(command)
			}

			log.Info("Firewall 关闭成功!")
		},
	}

	sysconfigCmd := &cobra.Command{
		Use:   "sysconfig",
		Short: "修改系统的sysconfig",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Sysconfig 	修改!")

			// 修改系统的sysconfig
			sysctlConfigFile := "/etc/sysctl.d/wdd-k8s.conf"

			if !utils.AppendOverwriteContentToFile(beans.SysctlConfig, sysctlConfigFile) {
				log.Error("[ModifySysConfigBastion] - error appending sysctl config to sysctl.d !")
				return
			}

			op.SingleLineCommandExecutor([]string{
				"sysctl",
				"-p",
				sysctlConfigFile,
			})

			log.Info("Sysconfig 修改成功!")
		},
	}

	// 通用工具安装
	commonToolsInstall := &cobra.Command{
		Use:   "tools",
		Short: "通用工具安装 利用本机的yum，apt等从网络安装常用的软件",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Common tool installation!")

			// Whether It can connect to internet
			if host_info.CanConnectInternet() <= 1 {
				log.Error("服务器无法连接互联网，无法执行tools")
				return
			}

			// package install
			// only support ubuntu(debian) centos(debian openEuler)
			packOperator := op.AgentPackOperator
			packOperator.PackageInit()

			os := host_info.ConfigCache.Agent.OS
			if os.IsUbuntuType {
				packOperator.Install(ubuntuCommonTools)
			} else {
				packOperator.Install(centosCommonTools)
			}
		},
	}

	sshCmd := &cobra.Command{
		Use:   "ssh",
		Short: "修改ssh配置",
	}
	addSSHSubcommands(sshCmd)

	// harbor 相关的函数
	harborCmd := &cobra.Command{
		Use:   "harbor",
		Short: "harbor相关的操作",
	}
	addHarborSubcommands(harborCmd)

	cmd.AddCommand(
		dockerCmd,
		dockerComposeCmd,
		harborCmd,
		swapCmd,
		commonToolsInstall,
		selinuxCmd,
		firewallCmd,
		sysconfigCmd,
		sshCmd,
		// 其他命令...
	)
}

// addHarborSubcommands 添加harbor子命令
func addHarborSubcommands(harborCmd *cobra.Command) {
	harborInstallCmd := &cobra.Command{
		Use:   "install",
		Short: "安装harbor 从本地安装 " + harborLocalInstallPath,
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("安装harbor")

			// 检查是否存在harbor目录
			if utils.FileExistAndNotNull("/root/wdd/harbor/harbor.yml") {
				log.Info("harbor已存在，无需安装!")
				return
			}

			// 解压harbor
			utils.UnzipFile(harborLocalInstallPath, "/root/wdd/")

			// 获取本机的内网IPv4地址
			configCache := host_info.ConfigCache
			if len(configCache.Agent.Network.Interfaces) == 0 {
				log.Error("没有获取到本机的ipv4地址，无法安装harbor! 请执行 info all !")
			}
			ip := configCache.Agent.Network.Interfaces[0].IPv4

			if ip == "" {
				log.Error("没有获取到本机的ipv4地址，无法安装harbor! 请执行 info all !")
				return
			}

			// 修改harbor的配置
			utils.AppendOverwriteContentToFile(beans.HarborYamlConfig, "/root/wdd/harbor/harbor.yml")
			utils.FindAndReplaceContentInFile("HarborHostName", ip, "/root/wdd/harbor/harbor.yml")

			if !utils.FileExistAndNotNull("/root/wdd/harbor/harbor.yml") {
				log.Error("修改harbor的配置失败! 请检查文件是否存在!")
				return
			}

			// 运行install.sh
			op.SingleLineCommandExecutor([]string{"cd", "/root/wdd/harbor"})
			ok, log1 := op.RealTimeCommandExecutor([]string{"/bin/bash", "/root/wdd/harbor/install.sh"})
			if !ok {
				log.Error("安装harbor失败: %s", log1)
				return
			}

			// wait to see the harbor is running
			log.Info("等待10秒 harbor启动...")
			time.Sleep(10 * time.Second)

			// 执行docker ps -a 查看 harbor名称的容器是否存在 Exit 或者 Restarting 则表示有错误！
			if !checkHarborIsRunning() {
				log.Error("harbor启动失败! 请检查日志!")
				return
			}

			log.Info("安装harbor成功!")

		},
	}

	harborUninstallCmd := &cobra.Command{
		Use:   "uninstall",
		Short: "卸载harbor",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("暂未实现harbor卸载!")

		},
	}

	harborStartCmd := &cobra.Command{
		Use:   "start",
		Short: "启动harbor",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("启动harbor")

			// 检查harbor是否存在
			if !utils.FileExistAndNotNull("/root/wdd/harbor/docker-compose.yml") {
				log.Error("harbor不存在! 请先安装harbor!")
				return
			}

			// 启动harbor
			op.SingleLineCommandExecutor([]string{"cd", "/root/wdd/harbor"})
			ok, log1 := op.SingleLineCommandExecutor([]string{"docker-compose", "up", "-d"})
			if !ok {
				log.Error("启动harbor失败: %s", log1)
				return
			}

			// 等待10秒
			time.Sleep(10 * time.Second)

			// 检查harbor是否启动成功
			if !checkHarborIsRunning() {
				log.Error("harbor启动失败! 请检查日志!")
				return
			}

			log.Info("启动harbor成功!")
			fmt.Println("")
			fmt.Println("")
		},
	}

	// 停止harbor
	harborStopCmd := &cobra.Command{
		Use:   "stop",
		Short: "停止harbor",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("停止harbor")

			// 检查harbor是否存在
			if !utils.FileExistAndNotNull("/root/wdd/harbor/docker-compose.yml") {
				log.Error("harbor不存在! 请先安装harbor!")
				return
			}

			// 进入harbor目录
			os.Chdir("/root/wdd/harbor")

			// 停止harbor
			ok, log1 := op.SingleLineCommandExecutor([]string{"docker-compose", "down"})
			if !ok {
				log.Error("停止harbor失败: %s", log1)
				return
			}

			log.Info("停止harbor成功!")
			fmt.Println("")
			fmt.Println("")
		},
	}

	harborCmd.AddCommand(harborInstallCmd, harborUninstallCmd, harborStartCmd, harborStopCmd)
}

// checkHarborIsRunning 检查harbor是否运行 如果存在Exit 或者 Restarting 则表示有错误！
func checkHarborIsRunning() bool {
	_, resultLog := op.PipeLineCommandExecutor([][]string{
		{
			"docker",
			"ps",
			"-a",
		},
		{
			"grep",
			"goharbor/",
		},
		{
			"grep",
			"-E",
			"'Exit|Restarting'",
		},
		{
			"wc",
			"-l",
		},
	})

	if strings.TrimSpace(resultLog[0]) != "0" {
		log.Error("harbor启动失败! 请检查日志!")
		return false
	}
	return true
}

func addSSHSubcommands(sshCmd *cobra.Command) {
	keyCmd := &cobra.Command{
		Use:   "key",
		Short: "安装默认的ssh-key",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("安装默认的ssh-key!")

			// 创建.ssh目录
			utils.CreateFolder("/root/.ssh")

			// 检查密钥是否存在
			if utils.FileExistAndNotNull("/root/.ssh/id_ed25519") &&
				utils.FileExistAndNotNull("/root/.ssh/id_ed25519.pub") &&
				utils.FindContentInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
				log.Info("SSH密钥已存在，无需重新安装。")
				return
			}

			// 下载标准的私钥和公钥
			if !utils.AppendOverwriteContentToFile(beans.Ed25519PrivateKey, "/root/.ssh/id_ed25519") {
				log.Error("[InstallDefaultSSHKey] - error appending private ssh key to authorized_keys !")
				return
			}
			if !utils.AppendOverwriteContentToFile(beans.Ed25519PublicKey, "/root/.ssh/id_ed25519.pub") {
				log.Error("[InstallDefaultSSHKey] - error appending public ssh key to authorized_keys !")
				return
			}

			// 写入到authorized_keys
			if !utils.AppendFileToFile("/root/.ssh/id_ed25519.pub", "/root/.ssh/authorized_keys") {
				log.Error("[InstallDefaultSSHKey] - error appending ssh key to authorized_keys !")
				return
			}

			// 设置权限
			op.SingleLineCommandExecutor([]string{
				"chmod",
				"600",
				"/root/.ssh/id_ed25519",
			})

			// 检查
			if utils.FindContentInFile("wdd@cmii.com", "/root/.ssh/authorized_keys") {
				log.Info("[InstallDefaultSSHKey] - install success !")
				fmt.Println("")
			} else {
				log.Error("[InstallDefaultSSHKey] - authorized_keys don't contain the ssh-pub key !")
			}

			fmt.Println("")
			fmt.Println("")
		},
	}

	portCmd := &cobra.Command{
		Use:   "port",
		Short: "修改ssh端口",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("修改ssh端口!")

			// 检查参数
			if len(args) > 0 {
				fmt.Printf("modify ssh port to: %s\n", args[0])
			}

			// 没有传递参数，使用默认参数
			port := "22333"
			log.Info("[ModifySSHPort] modify ssh port to: %s", port)

			// 文件中已经包含了Port 22333 则pass
			sshdPortString := fmt.Sprintf("Port %s", port)
			if utils.FindContentInFile(sshdPortString, "/etc/ssh/sshd_config") {
				log.Info("[ModifySSHPort] ssh port already modified to: %s", port)
			} else {
				// 修改ssh端口
				utils.AppendContentToFile(sshdPortString, "/etc/ssh/sshd_config")
			}

			// 重启ssh服务
			ok, resultLog := op.SystemdRestart("sshd")
			if !ok {
				log.Error("[ModifySSHPort] restart sshd error: %s", resultLog)
				return
			}

			log.Info("[ModifySSHPort] modify ssh port to: %s success!", port)
			fmt.Println("")
			fmt.Println("")

		},
	}

	configCmd := &cobra.Command{
		Use:   "config",
		Short: "修改ssh配置 为wdd默认配置!",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("修改ssh配置 为wdd默认配置!")

			// 备份文件
			if !utils.FileExistAndNotNull("/etc/ssh/sshd_config_back_wdd_ssh") {
				utils.AppendOverwriteContentToFile("/etc/ssh/sshd_config", "/etc/ssh/sshd_config_back_wdd_ssh")
			}

			// 修改ssh配置
			utils.AppendOverwriteContentToFile(beans.DefaultSshdConfig, "/etc/ssh/sshd_config")

			// 重启ssh服务
			ok, resultLog := op.SystemdRestart("sshd")
			if !ok {
				log.Error("sshd 重启失败: %s", resultLog)
				return
			}

			log.Info("[sshd配置修改] 成功!")
			fmt.Println("")
			fmt.Println("")

		},
	}

	sshCmd.AddCommand(keyCmd, portCmd, configCmd)
}

// 添加docker子命令
func addDockerSubcommands(cmd *cobra.Command) {
	onlineCmd := &cobra.Command{
		Use:   "online [version]",
		Short: "网络安装Docker, 如果不指定参数默认安装20.10.24版本",

		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("网络安装Docker, 如果不指定参数默认安装20.10.24版本")

			// 检查参数
			if len(args) > 0 {
				fmt.Printf("Installing Docker version: %s\n", args[0])
			}

			// 安装docker
			packOperator := op.AgentPackOperator
			packOperator.PackageInit()

			configCache := host_info.ConfigCache
			if configCache.Agent.OS.IsUbuntuType {
				// 安装apt-transport-https ca-certificates curl gnupg software-properties-common 依赖部分
				packOperator.Install([]string{"apt-transport-https", "ca-certificates", "curl", "gnupg", "software-properties-common"})

				// 安装docker的 gpg key
				dockerGPGFilePath := "/etc/apt/keyrings/docker.gpg"
				dockerAPTFilePath := "/etc/apt/sources.list.d/docker.list"
				dockerGPGSource := "https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg"
				dockerAPTSource := "https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu"

				// 创建docker的 gpg key 文件
				utils.CreateFolder("/etc/apt/keyrings")

				// 删除docker的 gpg key 文件
				utils.RemoveFile(dockerGPGFilePath)
				utils.RemoveFile(dockerAPTFilePath)

				// 如果可以访问外网，则使用外网源
				if configCache.Agent.Network.Internet == 9 {
					dockerGPGSource = "https://download.docker.com/linux/ubuntu/gpg"
					dockerAPTSource = "https://download.docker.com/linux/ubuntu"
				}

				ok, l2 := op.PipeLineCommandExecutor([][]string{
					{
						"curl",
						"-fsSL",
						dockerGPGSource,
					},
					{
						"gpg",
						"--dearmor",
						"-o",
						dockerGPGFilePath,
					},
				})

				if !ok {
					log.Error("下载docker gpg文件失败: %s", l2)
					return
				}

				if !utils.FileExistAndNotNull(dockerGPGFilePath) {
					log.Error("添加gpg失败！")
					return
				}

				op.SingleLineCommandExecutor([]string{
					"chmod",
					"a+r",
					dockerGPGFilePath,
				},
				)

				if configCache.Agent.OS.OSReleaseCode == "" {
					log.Error("获取系统发行版代号失败！ 无法安装docker!")
					return
				}

				dockerAPTSourceCommand := "deb [arch=" + configCache.Agent.OS.Arch + " signed-by=" + dockerGPGFilePath + "] " + dockerAPTSource + " " + configCache.Agent.OS.OSReleaseCode + " stable"

				log.Info("dockerAPTSourceCommand is => %s ", dockerAPTSourceCommand)

				utils.AppendOverwriteContentToFile(dockerAPTSourceCommand, dockerAPTFilePath)

				// 强制初始化APT update
				packOperator.PackageInitForce()

				// 20.04 default
				specificDockerVersion := "5:20.10.24~3-0~ubuntu-" + configCache.Agent.OS.OSReleaseCode
				// apt-cache madison docker-ce | grep 20.10.20 | awk '{print$3}'

				// get by method
				ok, log4 := op.PipeLineCommandExecutor([][]string{
					{
						"apt-cache",
						"madison",
						"docker-ce",
					},
					{
						"grep",
						"20.10.20",
					},
					{
						"awk",
						"'{print$3}'",
					},
				})
				if ok && log4 != nil && len(log4) > 0 {
					specificDockerVersion = strings.TrimSpace(log4[0])
					fmt.Println("get docker version from online => " + specificDockerVersion)
				}

				log.Info("需要安装的docker版本为 => %s", specificDockerVersion)

				dockerStaffList := []string{
					"docker-ce=" + specificDockerVersion,
					"docker-ce-cli=" + specificDockerVersion,
					"containerd.io",
					"docker-compose-plugin",
				}

				ok = packOperator.Install(dockerStaffList)
				if !ok {
					log.Error("安装docker存在问题，请检查!")
					return
				}

			} else {
				log.Error("当前系统不是ubuntu系统，暂时无法安装docker! 请使用local的方式安装")
				return
			}

			log.Info("安装docker成功!")

			// 启动docker
			op.SystemdUp("docker")
			op.SystemdEnable("docker")

			// 检查docker是否启动成功
			ok, resultLog := op.SystemIsRunning("docker")
			if !ok {
				log.Error("docker启动失败: %s", resultLog)
				return
			}

			log.Info("docker启动成功! ")
			fmt.Println("")
			fmt.Println("")

		},
	}

	removeCmd := &cobra.Command{
		Use:   "remove",
		Short: "卸载Docker",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("Removing Docker...")

			// 检查docker是二进制安装还是通过包安装的
			dockerExists := op.CommandExistsByPath("docker")
			if !dockerExists {
				log.Info("Docker 未安装，无需卸载!")
				return
			}

			// 卸载docker
			packOperator := op.AgentPackOperator
			packOperator.PackageInit()
			packOperator.Remove([]string{"docker-ce", "docker-ce-cli", "containerd.io", "docker-buildx-plugin", "docker-compose-plugin"})

			// 删除docker目录
			utils.RemoveFile("/usr/bin/docker")
			utils.RemoveFile("/usr/bin/docker-compose")
			utils.RemoveFile("/usr/bin/docker-buildx")
			utils.RemoveFile("/usr/bin/docker-compose-plugin")
			utils.RemoveFile("/usr/bin/containerd")

			// 删除docker的配置文件 systemd
			utils.RemoveFile("/etc/systemd/system/docker.service")
			utils.RemoveFile("/etc/systemd/system/docker.socket")
			utils.RemoveFile("/etc/systemd/system/containerd.service")
			utils.RemoveFile(beans.ContainerdServiceFile)
			utils.RemoveFile(beans.DockerSocketFile)
			utils.RemoveFile(beans.DockerServiceFile)

			// 删除docker的日志文件
			utils.RemoveFile("/var/log/docker")

			log.Info("Docker 卸载成功!")

		},
	}

	localCmd := &cobra.Command{
		Use:   "local",
		Short: "本地安装Docker, 默认安装20.10.15版本, 安装文件应该为 " + dockerLocalInstallPath,
		Run: func(cmd *cobra.Command, args []string) {

			log.Info("Installing Docker from local file: %s", dockerLocalInstallPath)

			exist := utils.FileExistAndNotNull(dockerLocalInstallPath)
			if !exist {
				log.Error("Docker local install file not found: %s", dockerLocalInstallPath)
				return
			}

			// 解压文件
			utils.UnzipFile(dockerLocalInstallPath, "/root/wdd/")

			// 设置权限
			dockerBinList := []string{
				"docker-init",
				"containerd",
				"ctr",
				"runc",
				"dockerd",
				"docker-proxy",
				"containerd-shim",
				"docker",
				"containerd-shim-runc-v2",
			}

			// 删除旧的docker 二进制文件
			for _, bin := range dockerBinList {
				utils.RemoveFile("/usr/bin/" + bin)
			}

			// 安装docker
			err := utils.MoveFolerToAnother("/root/wdd/docker/", "/usr/bin")
			if err != nil {
				log.Error("Failed to move Docker binaries: %s", err.Error())
				return
			}

			for _, bin := range dockerBinList {
				ok, resultLog := op.SingleLineCommandExecutor([]string{"chmod", "777", "/usr/bin/" + bin})
				if !ok {
					log.Error("Failed to set permissions for Docker binaries: %s", resultLog)
				}
			}

			// 配置并启动Docker服务
			// systemd daemonize docker
			utils.AppendOverwriteContentToFile(beans.ContainerdDaemonService, beans.ContainerdServiceFile)
			if !utils.FileExistAndNotNull(beans.ContainerdServiceFile) {
				log.Error("docker deamon file not exists !")
			}
			utils.AppendOverwriteContentToFile(beans.DockerSocketDaemonService, beans.DockerSocketFile)
			if !utils.FileExistAndNotNull(beans.DockerSocketFile) {
				log.Error("docker deamon file not exists !")
			}
			utils.AppendOverwriteContentToFile(beans.DockerDaemonService, beans.DockerServiceFile)
			if !utils.FileExistAndNotNull(beans.DockerServiceFile) {
				log.Error("docker deamon file not exists !")
			}
			log.Info("docker dameon file append success !")

			ok, resultLog := op.SystemdDaemonReload()
			if !ok {
				log.Error("daemon reload error ! %s", resultLog)
				return
			}

			op.SingleLineCommandExecutor([]string{"systemctl", "unmask", "containerd"})
			op.SingleLineCommandExecutor([]string{"systemctl", "unmask", "docker.socket"})
			op.SingleLineCommandExecutor([]string{"systemctl", "unmask", "docker"})

			op.SingleLineCommandExecutor([]string{"groupadd", "docker"})
			op.SingleLineCommandExecutor([]string{"usermod", "-aG", "docker", "root"})
			op.SingleLineCommandExecutor([]string{"newgrp", "docker"})

			systemdUp, resultLog := op.SystemdUp("containerd")
			if !systemdUp {
				log.Error("[InstallDockerBastion] - start containerd service error ! %s", resultLog)
				return
			}

			ok, resultLog = op.SystemdUp("docker.socket")
			if !ok {
				log.Error("[InstallDockerBastion] - start docker.socket error ! %s", resultLog)
				return
			}

			ok, resultLog = op.SystemdUp("docker")
			if !ok {
				log.Error("[InstallDockerBastion] - start docker service error ! %s", resultLog)
				return
			}

			log.Info("Docker installed successfully from local file!")
		},
	}

	configCmd := &cobra.Command{
		Use:   "config",
		Short: "配置Docker",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("")
			log.Info("配置Docker-此命令仅在主节点执行即可")

			// 检查docker是否安装
			dockerExists := op.CommandExistsByPath("docker")
			if !dockerExists {
				log.Error("Docker 未安装，请先安装 Docker")
				return
			}

			// 获取当前内网IP
			ip := host_info.ConfigCache.Agent.Network.Interfaces[0].IPv4
			if ip == "" {
				log.Error("获取当前内网IP失败, 无法进行docker config配置！")
				return
			}

			// 配置docker的daemon.json
			if !utils.AppendOverwriteContentToFile(beans.DockerDeamonConfig, "/etc/docker/daemon.json") {
				log.Error("配置docker的daemon.json失败！")
				return
			}

			// 替换其中的字段
			utils.FindAndReplaceContentInFile("DockerRegisterDomain", ip, "/etc/docker/daemon.json")

			// 重启docker
			op.SystemdRestart("docker")

			// 检查docker是否重启成功
			ok, resultLog := op.SystemIsRunning("docker")
			if !ok {
				log.Error("docker daemon config 失败, docker重启失败: %s", resultLog)
				return
			}

			daemonJsonContent := utils.ReadAllContentFromFile("/etc/docker/daemon.json")
			log.Info("修改daemon config 成功, docker重启成功!")
			utils.BeautifulPrintListWithTitle(daemonJsonContent, "docker daemon.json")

			fmt.Println("")
			fmt.Println("")
		},
	}

	cmd.AddCommand(onlineCmd, removeCmd, localCmd, configCmd)
}

func addDockerComposeSubcommands(cmd *cobra.Command) {

	installCmd := &cobra.Command{
		Use:   "online [version]",
		Short: "安装Docker Compose",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Installing Docker Compose...")

			// 检查参数
			if len(args) > 0 {
				fmt.Printf("Installing Docker Compose version: %s\n", args[0])
			}

			// 默认安装最新版本
			version := "latest"
			if len(args) > 0 {
				version = args[0]
			}

			// 如果是最新版本，则通过GitHub API查询
			if version == "latest" {
				latestVersion, err := op.GetLatestGithubReleaseVersion("docker", "compose")
				if err != nil {
					log.Error("获取Docker Compose最新版本失败: %s", err)
				} else {
					version = latestVersion
					log.Info("获取到Docker Compose最新版本: %s", version)
				}
			}

			log.Info("安装 Docker Compose 版本: %s", version)

			// 检查是否可以连接互联网
			if host_info.CanConnectInternet() <= 1 {
				log.Error("服务器无法连接互联网，无法在线安装 Docker Compose")
				return
			}

			// 检查 Docker 是否已安装
			dockerExists := op.CommandExistsByPath("docker")
			if !dockerExists {
				log.Error("Docker 未安装，请先安装 Docker")
				return
			}

			// 根据架构选择合适的下载链接
			arch := runtime.GOARCH
			downloadURL := fmt.Sprintf("https://github.com/docker/compose/releases/download/%s/docker-compose-linux-%s", version, arch)

			log.Info("Downloading Docker Compose from: %s", downloadURL)
			// 下载 Docker Compose
			ok, ccc := utils.DownloadFile(downloadURL, "/usr/local/bin/docker-compose")
			if !ok {
				log.Error("下载 Docker Compose 失败: %s", ccc)
				return
			}

			// 设置执行权限
			chmodCmd := []string{"chmod", "+x", "/usr/local/bin/docker-compose"}
			ok, resultLog := op.SingleLineCommandExecutor(chmodCmd)
			if !ok {
				log.Error("设置 Docker Compose 权限失败: %s", resultLog)
				return
			}

			// 创建软链接
			linkCmd := []string{"ln", "-sf", "/usr/local/bin/docker-compose", "/usr/bin/docker-compose"}
			op.SingleLineCommandExecutor(linkCmd)

			// 验证安装
			verifyCmd := []string{"/usr/local/bin/docker-compose", "version"}
			ok, resultLog = op.SingleLineCommandExecutor(verifyCmd)
			if !ok {
				log.Error("Docker Compose 安装验证失败: %s", resultLog)
				return
			}

			log.Info("Docker Compose 安装成功: %s", resultLog)

		},
	}

	removeCmd := &cobra.Command{
		Use:   "remove",
		Short: "卸载Docker Compose",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Removing Docker Compose...")

			if utils.RemoveFile("/usr/local/bin/docker-compose") {
				log.Info("Docker Compose removed successfully!")
			} else {
				log.Error("Failed to remove Docker Compose!")
			}

		},
	}

	localCmd := &cobra.Command{
		Use:   "local",
		Short: "本地安装DockerCompose 安装文件应该为 " + dockerComposeLocalInstallPath,
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Installing Docker Compose from local file...")

			exist := utils.FileExistAndNotNull(dockerComposeLocalInstallPath)
			if !exist {
				log.Error("Docker local install file not found: %s", dockerComposeLocalInstallPath)
				return
			}

			// move file to /usr/local/bin
			err := utils.MoveFileToAnother(dockerComposeLocalInstallPath, "/usr/local/bin/docker-compose")
			if err != nil {
				log.Error("Failed to move Docker Compose binaries: %s", err.Error())
				return
			}

			// set permission
			chmodCmd := []string{"chmod", "+x", "/usr/local/bin/docker-compose"}
			ok, resultLog := op.SingleLineCommandExecutor(chmodCmd)
			if !ok {
				log.Error("Failed to set permissions for Docker Compose binaries: %s", resultLog)
				return
			}

			// 创建软链接
			linkCmd := []string{"ln", "-sf", "/usr/local/bin/docker-compose", "/usr/bin/docker-compose"}
			op.SingleLineCommandExecutor(linkCmd)

			// 验证安装
			verifyCmd := []string{"/usr/local/bin/docker-compose", "version"}
			ok, resultLog = op.SingleLineCommandExecutor(verifyCmd)
			if !ok {
				log.Error("Docker Compose 安装验证失败: %s", resultLog)
				return
			}

			log.Info("Docker Compose installed successfully from local file!")
		},
	}

	versionCmd := &cobra.Command{
		Use:   "version",
		Short: "查看Docker Compose版本",
		Run: func(cmd *cobra.Command, args []string) {
			log.Info("Docker Compose version...")
			ok, resultLog := op.SingleLineCommandExecutor([]string{"docker-compose", "--version"})
			if !ok {
				log.Error("Failed to get Docker Compose version: %s", resultLog)
				return
			}
			log.Info("Docker Compose version: %s", resultLog)
		},
	}

	cmd.AddCommand(
		installCmd,
		removeCmd,
		localCmd,
		versionCmd,
	)

}
