package executor

import (
	"strconv"
	"strings"
)

func BuildAgentOsOperator(osInfo string, ossOfflinePrefix string) *AgentOsOperator {

	// todo build from env
	AgentOsOperatorCache = &AgentOsOperator{
		InstallCommandPrefix: []string{
			"apt-get", "install", "--allow-downgrades", "-y",
		},
		RemoveCommandPrefix: []string{"apt", "remove", "-y"},
		CanAccessInternet:   true,
		IsOsTypeUbuntu:      true,
		IsAgentInnerWall:    false,
		AgentArch:           "amd64",
		AgentOSReleaseCode:  "focal",
		AgentServerInfo:     nil,
		OssOfflinePrefix:    ossOfflinePrefix,
	}

	// os type
	detectByOsType(AgentOsOperatorCache, osInfo)

	// internet
	detectByInternet(AgentOsOperatorCache)

	return AgentOsOperatorCache
}

func detectByOsType(os *AgentOsOperator, osInfo string) {

	ubuntuOsReleaseCode := [][]string{
		{
			"cat",
			"/etc/os-release",
		},
		{
			"grep",
			"CODE",
		},
		{
			"head",
			"-1",
		},
		{
			"cut",
			"-d",
			"=",
			"-f",
			"2",
		},
	}

	if strings.HasPrefix(osInfo, "Ce") {
		// centos
		os.IsOsTypeUbuntu = false
		os.InstallCommandPrefix = []string{
			"yum", "install", "-y",
		}
		os.RemoveCommandPrefix = []string{
			"yum", "remove",
		}

	} else {
		// ubuntu
		os.IsOsTypeUbuntu = true
		os.RemoveCommandPrefix = []string{"apt", "remove", "-y"}
		os.InstallCommandPrefix = []string{
			"apt-get", "install", "--allow-downgrades", "-y",
		}

		// os release code
		ok, resultLog := PipelineCommandExecutor(ubuntuOsReleaseCode)
		if ok {
			os.AgentOSReleaseCode = resultLog[0]
		} else {
			os.AgentOSReleaseCode = "UNKNOWN"
		}

	}

}

func detectByInternet(os *AgentOsOperator) {

	outsideTestUrl := "www.google.com"
	innerTestUrl := "www.baidu.com"

	testInternetCommand := []string{
		"curl",
		"-o",
		"/dev/null",
		"-m",
		"5",
		"-s",
	}

	if PureResultSingleExecute(append(testInternetCommand, outsideTestUrl)) {
		os.CanAccessInternet = true
		os.IsAgentInnerWall = false
	} else if PureResultSingleExecute(append(testInternetCommand, innerTestUrl)) {
		os.CanAccessInternet = true
		os.IsAgentInnerWall = true
	} else {
		os.CanAccessInternet = false
		os.IsAgentInnerWall = true
	}

	log.InfoF("[Agent Network Status] - Can Access Internet => %s  Inner CN => %s", strconv.FormatBool(os.CanAccessInternet), strconv.FormatBool(os.IsAgentInnerWall))

}
