package main

import (
	"fmt"
	"log"
	"os/exec"
	"strings"

	pub "git.zhiweidata.top/taotengfei/AD-Control-Golang/public"
)

func checkOffice(path string) bool {
	out, err := execcmd(path, "/dstatus")
	if err != nil {
		log.Println(string(out))
		log.Println(err.Error())
		return false
	}
	outstr := string(out)
	if strings.Contains(outstr, "---LICENSED---") {
		log.Printf("当前已激活Office")
		return false
	} else if strings.Contains(outstr, "---OOB_GRACE---") {
		log.Printf("当前未激活Office")
		return true
	} else if strings.Contains(outstr, "No installed product keys detected") {
		log.Printf("当前未激活Office")
		return true
	}
	return true
}
func getOfficePath() (string, error) {
	var reg [4][2]string
	var path string
	reg[0][0] = `SOFTWARE\Microsoft\Office\16.0\Outlook\InstallRoot`
	// reg[0][1] = "Office 2016 ProPlus"
	reg[1][0] = `SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\Software\Wow6432Node\Microsoft\Office\16.0\Common\InstallRoot`
	// reg[1][1] = "Office 2019 ProPlus"
	for i := 0; i < len(reg); i++ {
		path, _ = query_key_one(reg[i][0], "Path")
		if path != "" {
			return path, nil
		}

	}
	if path == "" {
		return "", fmt.Errorf("不支持该版本的Office")
	}
	return path, nil

}
func setOfficeSKU(path string) error {
	path = path + `root\Licenses16\`
	arr := []string{
		"ProPlus2019VL_KMS_Client_AE-ppd.xrm-ms",
		"ProPlus2019VL_KMS_Client_AE-ul.xrm-ms",
		"ProPlus2019VL_KMS_Client_AE-ul-oob.xrm-ms",
		"ProPlus2019VL_MAK_AE-pl.xrm-ms",
		"ProPlus2019VL_MAK_AE-ppd.xrm-ms",
		"ProPlus2019VL_MAK_AE-ul-oob.xrm-ms",
		"ProPlus2019VL_MAK_AE-ul-phn.xrm-ms",
		// "client-issuance-bridge-office.xrm-ms",
		// "client-issuance-root.xrm-ms",
		// "client-issuance-root-bridge-test.xrm-ms",
		// "client-issuance-stil.xrm-ms",
		// "client-issuance-ul.xrm-ms",
		// "client-issuance-ul-oob.xrm-ms",
		// "pkeyconfig-office.xrm-ms",
		// "ProPlusVL_KMS_Client-ppd.xrm-ms",
		// "ProPlusVL_KMS_Client-ul.xrm-ms",
		// "ProPlusVL_KMS_Client-ul-oob.xrm-ms",
		// "ProjectProVL_KMS_Client-ppd.xrm-ms",
		// "ProjectProVL_KMS_Client-ul-oob.xrm-ms",
		// "ProjectProVL_KMS_Client-ul.xrm-ms",
		// "VisioProVL_KMS_Client-ppd.xrm-ms",
		// "VisioProVL_KMS_Client-ul-oob.xrm-ms",
		// "VisioProVL_KMS_Client-ul.xrm-ms",
		// "SkypeforBusinessVL_KMS_Client-ppd.xrm-ms",
		// "SkypeforBusinessVL_KMS_Client-ul.xrm-ms",
		// "SkypeforBusinessVL_KMS_Client-ul-oob.xrm-ms",
		// "client-issuance-bridge-office.xrm-ms",
		// "client-issuance-root.xrm-ms",
		// "client-issuance-root-bridge-test.xrm-ms",
		// "client-issuance-stil.xrm-ms",
		// "client-issuance-ul.xrm-ms",
		// "client-issuance-ul-oob.xrm-ms",
		// "pkeyconfig-office.xrm-ms",
	}
	for _, i := range arr {
		cmd := fmt.Sprintf(`powershell cscript C:\Windows\SysWOW64\slmgr.vbs /ilc "%s%s" //nologo`, path, i)
		out := string(pub.Execcmd_output(cmd))
		if strings.Contains(out, "错误") {
			return fmt.Errorf(out)
		}
	}
	log.Println("SKU设置完毕")
	return nil
}

func getOfficeVersion(path string) (string, error) {
	var officeVersion string

	out, err := execcmd_filter(path, "/dstatus", `"LICENSE.NAME"`)
	if err != nil {
		return "", err
	}
	outstr := string(out)
	if strings.Contains(outstr, "Office16ProPlus") {
		log.Printf("Office版本为2016专业增强版")
		officeVersion = "Office 16.0 ProPlus"
	} else {
		return "", fmt.Errorf("查询错误或不支持该版本: %s", outstr)
	}
	return officeVersion, err
}
func activeOffice() error {
	log.Printf("正在检查Office的安装路径")
	path, err := getOfficePath()
	if err != nil {
		return err
	}
	path = strings.ToLower(path)
	if strings.Contains(path, `root\`) {
		path = strings.Split(path, `root\`)[0]
	}
	log.Printf("Office的基础路径:%s", path)
	path_ospp := path + `Office16\`
	log.Printf("检查激活Office状态")
	if !checkOffice(path_ospp) {
		return nil
	}
	log.Printf("准备激活Office")

	// log.Printf("获取Office版本")
	// officeVersion, err := getOfficeVersion(path_ospp)
	// if err != nil {
	// 	return err
	// }

	// 从服务器获取密钥
	officeVersion := "Office 2019 ProPlus"
	pub.SendBoomServer(pub.Msg_Boom_Active, officeVersion)
	if pub.MS.Error {
		return fmt.Errorf(pub.MS.Errmsg)
	}
	key := pub.MS.S
	log.Printf("请求到%s的版本的密钥为%s", officeVersion, key)
	if err := setOfficeSKU(path); err != nil {
		return err
	}

	out, err := execcmd(path_ospp, "/sethst:192.168.0.21")
	outstr := string(out)
	if err != nil {
		if strings.Contains(outstr, "0x80070005") {
			return fmt.Errorf("请使用管理员权限打开本程序")
		} else if strings.Contains(outstr, "The Software Licensing Service reported that the action requires administrator privilege") {
			return fmt.Errorf("请使用管理员权限打开本程序")
		} else {
			log.Println(outstr)
		}
	}
	if strings.Contains(outstr, "Successfully applied setting") {
		log.Printf("kms的IP设置成功")
	}
	out, err = execcmd(path_ospp, "/setprt:1688")
	outstr = string(out)
	if err != nil {
		if strings.Contains(outstr, "0x80070005") {
			return fmt.Errorf("请使用管理员权限打开本程序")
		} else if strings.Contains(outstr, "The Software Licensing Service reported that the action requires administrator privilege") {
			return fmt.Errorf("请使用管理员权限打开本程序")
		} else if strings.Contains(outstr, "No Office KMS licenses were found on the system.") {
			return fmt.Errorf("没有找到KMS密钥")
		} else {
			log.Println(outstr)
		}
	}
	if strings.Contains(outstr, "Successfully applied setting") {
		log.Printf("kms的port设置成功")
	} else {
		log.Println(outstr)
	}

	out, err = execcmd(path_ospp, "/inpkey:"+key)
	outstr = string(out)
	if err != nil {
		if strings.Contains(outstr, "0x80070005") {
			return fmt.Errorf("请使用管理员权限打开本程序")
		} else if strings.Contains(outstr, "The Software Licensing Service reported that the action requires administrator privilege") {
			return fmt.Errorf("请使用管理员权限打开本程序")
		} else if strings.Contains(outstr, "The Software Licensing Service reported that the product SKU is not found.") {
			return fmt.Errorf("SKU安装错误")

		} else if strings.Contains(outstr, "The Software Licensing Service reported that the product key is invalid") {
			return fmt.Errorf("激活使用了错误的密钥")
		}
	}
	if strings.Contains(outstr, "Product key installation successful") {
		log.Printf("产品密钥激活成功")
	} else {
		log.Println(outstr)
	}
	return nil

}

func execcmd(path, args1 string) ([]byte, error) {
	cmd := exec.Command("powershell", `cscript`, "OSPP.VBS", args1, "//nologo")
	cmd.Dir = path
	out, err := cmd.CombinedOutput()

	if err != nil {
		return pub.ToChineseChar(out), err
	}
	return pub.ToChineseChar(out), nil
}

func execcmd_filter(path, args1, args2 string) ([]byte, error) {
	cmd := exec.Command("powershell", `cscript`, "OSPP.VBS", args1, "//nologo", "|", "findstr", args2)
	cmd.Dir = path
	out, err := cmd.CombinedOutput()
	if err != nil {
		return pub.ToChineseChar(out), err
	}
	return pub.ToChineseChar(out), nil
}
