package feishu

import (
	"AutoSSO/Pbs"
	"AutoSSO/gcpsso"
	"crypto/md5"
	"fmt"
	"github.com/go-ini/ini"
	"io/ioutil"
	"strings"
	"time"
)

/*
监控 /config/gcp_custom_role.ini 文件中各个键的值是否有变化，实现一个函数来比较文件在两个不同时间点的内容。
这个函数可以返回一个数组，每个数组元素包含某个键值对的变化情况，格式为 键:角色:动作，其中动作可以是 add 或 del。
*/

// 文件路径常量
const iniFilePath = `./config/gcp_custom_role.ini`
const all_instance_path = `./config/instancesid.txt`
const del_instance_path = `./config/deleted_permission.txt`

// 计算文件的 MD5 哈希值
func calculateFileMD5(filePath string) (string, error) {
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		return "", err
	}
	hash := md5.Sum(data)
	return fmt.Sprintf("%x", hash), nil
}

// 读取 ini 文件中的值
func readIniValues() (map[string][]string, error) {
	cfg, err := ini.Load(iniFilePath)
	if err != nil {
		return nil, err
	}

	rolesMap := make(map[string][]string)
	for _, section := range cfg.Sections() {
		if section.Name() == "DEFAULT" {
			continue
		}
		roles := section.Key("roles").String()
		roles = strings.TrimSpace(roles)
		rolesList := strings.Split(roles, "|")
		rolesMap[section.Name()] = rolesList
	}
	return rolesMap, nil
}

// 比较两个角色列表
func compareRoles(oldRoles, newRoles []string) (added, removed []string) {
	oldRolesMap := make(map[string]bool)
	newRolesMap := make(map[string]bool)

	for _, role := range oldRoles {
		oldRolesMap[role] = true
	}
	for _, role := range newRoles {
		newRolesMap[role] = true
	}

	for role := range oldRolesMap {
		if !newRolesMap[role] {
			removed = append(removed, role)
		}
	}

	for role := range newRolesMap {
		if !oldRolesMap[role] {
			added = append(added, role)
		}
	}

	return added, removed
}

// 监控 ini 文件变化
func MonitorIniChanges() {
	var previousMD5 string
	var previousValues map[string][]string
	for {
		currentMD5, err := calculateFileMD5(iniFilePath)
		if err != nil {
			fmt.Println("Error calculating MD5:", err)
			continue
		}

		if previousMD5 != "" && currentMD5 != previousMD5 {
			currentValues, err := readIniValues()
			if err != nil {
				fmt.Println("Error reading ini values:", err)
				continue
			}

			var changes []string
			for key, oldRoles := range previousValues {
				newRoles, exists := currentValues[key]
				if exists {
					added, removed := compareRoles(oldRoles, newRoles)
					for _, role := range added {
						changes = append(changes, fmt.Sprintf("%s:%s:add", key, role))
					}
					for _, role := range removed {
						changes = append(changes, fmt.Sprintf("%s:%s:del", key, role))
					}
				} else {
					for _, role := range oldRoles {
						changes = append(changes, fmt.Sprintf("%s:%s:del", key, role))
					}
				}
			}

			for key, newRoles := range currentValues {
				if _, exists := previousValues[key]; !exists {
					for _, role := range newRoles {
						changes = append(changes, fmt.Sprintf("%s:%s:add", key, role))
					}
				}
			}

			if len(changes) > 0 {
				//fmt.Println("Changes detected:")
				for _, change := range changes {
					fmt.Println("change:" + change)
					/*
						Changes detected:
						DBaaS-Prod-Admin-Role:roles/bigquery.admin:add
						Changes detected:
						DBaaS-Prod-Admin-Role:roles/editor:add
						DBaaS-Prod-Admin-Role:roles/iam.securityAdmin:add
						DBaaS-Prod-Admin-Role:roles/bigquery.admin:del
						Changes detected:
						DBaaS-Prod-Admin-Role:roles/iam.securityAdmin:del
						DBaaS-Prod-Admin-Role:roles/editor:del
					*/
					//开始授予或回收权限

					//把 ini 权限配置表中变化的权限分配给通过
					GCP_Config_permissions_waitfile(change)

					//把 ini 权限配置表中变化的权限分配给通过飞书获取 instance 得到的user上
					GCP_Config_permissions_instance(change)
					fmt.Println("")
				}
			}

			previousValues = currentValues
		} else if previousMD5 == "" {
			previousValues, err = readIniValues()
			if err != nil {
				fmt.Println("Error reading initial ini values:", err)
				continue
			}
		}

		previousMD5 = currentMD5
		time.Sleep(5 * time.Second)
	}
}

// 带入键:角色:动作 执行 GCP 权限配置操作，这里配置 wait_delete_up.txt 中的权限
func GCP_Config_permissions_waitfile(cper string) {
	spis := strings.Split(cper, ":")
	gcp_custom_role := spis[0]    //键即为自定义 role 名称
	gcp_managed_role := spis[1]   //角色即为 GCP 管理的 role
	gcp_execute_action := spis[2] //指定的动作

	linestrs := Pbs.Read_txt_File(`./config/wait_delete_up.txt`)
	if len(linestrs) >= 1 {
		for _, linestr := range linestrs {
			linestr = strings.TrimSpace(linestr)
			if linestr != "" {
				spi := strings.Split(linestr, "|")
				if len(spi) > 2 {
					pdstr := isAllDigits(spi[1])
					if pdstr == false { //GCP
						current_account := spi[1]
						current_user := spi[2]
						current_role := spi[3]
						if gcp_custom_role == current_role {
							switch gcp_execute_action {
							case "add":
								fmt.Println("Add user permissions:" + current_account + " " + current_user + " " + gcp_managed_role)
								gcpsso.GCP_add_role_user_ini(current_account, current_user, gcp_managed_role)
								break
							case "del":
								fmt.Println("Remove user permissions:" + current_account + " " + current_user + " " + gcp_managed_role)
								gcpsso.GCP_del_role_user_ini(current_account, current_user, gcp_managed_role)
								break
							}
						}

					}
				}
			}
		}
	}
}

// 带入 键:角色:动作 执行 GCP 权限配置操作，这里通过飞书的 instance 得到的 user 权限信息
func GCP_Config_permissions_instance(cper string) {
	spi := strings.Split(cper, ":")
	gcp_custom_role := spi[0]    //键即为自定义 role 名称
	gcp_managed_role := spi[1]   //角色即为 GCP 管理的 role
	gcp_execute_action := spi[2] //指定的动作

	active_instances := GCP_Active_feishu_instanceID()
	for _, instance := range active_instances {
		fsdata, err := Instanceid_To_Feishudata(instance)
		if err == nil {
			cloud_type, cerr := Is_AWS_GCP(fsdata)
			if cerr != nil {
				continue
			}
			if cloud_type == "GCP" {
				if fsdata.email != "" && fsdata.apptype == true && fsdata.prodaccount != "" && fsdata.ssopermissions[0] != "" && fsdata.isovertime == false && fsdata.isapproved == true {
					//fmt.Println(fsdata)
					for _, current_custom_role := range fsdata.ssopermissions {
						current_custom_role = strings.TrimSpace(current_custom_role)
						if current_custom_role != "" {
							if current_custom_role == gcp_custom_role {
								switch gcp_execute_action {
								case "add":
									fmt.Println("Add user permissions:" + fsdata.prodaccount + " " + fsdata.email + " " + gcp_managed_role)
									gcpsso.GCP_add_role_user_ini(fsdata.prodaccount, fsdata.email, gcp_managed_role)
									//fmt.Println("")
									break
								case "del":
									fmt.Println("Remove user permissions:" + fsdata.prodaccount + " " + fsdata.email + " " + gcp_managed_role)
									gcpsso.GCP_del_role_user_ini(fsdata.prodaccount, fsdata.email, gcp_managed_role)
									//fmt.Println("")
									break
								}
							}
						}
					}
				}
			}
		}
	}
}

// 通过飞书的instance 查看目前还有哪些 instance 没有被回收权限
func GCP_Active_feishu_instanceID() []string {
	var ret_instances []string
	all_instances := Pbs.Read_txt_File(all_instance_path)
	del_instancestr := Read_txt_File(del_instance_path)
	for _, instance := range all_instances {
		instance = strings.TrimSpace(instance)
		if instance != "" {
			if strings.Contains(del_instancestr, instance) == false { //没有被删除的说明目前权限还在 GCP 中
				ret_instances = append(ret_instances, instance)
			}
		}
	}
	return ret_instances
}
