package feishu

import (
	"AutoSSO/awssso"
	"AutoSSO/gcpsso"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"
)

// This array stores the instances that have not yet passed
var Wait_Addpermiss_Ins []string

/*
Monitor for new application IDs
*/
func Check_New_Instance_IDs() {
	for {
		Instrances_IDS, err := Get_New_Instanceids()
		if err != nil {
			continue
		}
		idsspi := strings.Split(Instrances_IDS, "\n")
		if len(idsspi) >= 1 {
			for _, insid := range idsspi {
				if strings.Contains(Instances_IDS_Str, insid) == false {
					Instances_IDS_Str = Instances_IDS_Str + insid + "\n"
					WriteData_To_File(Config_instance_Path, Instances_IDS_Str)
					//fmt.Println(insid)
					//这是新的insid，开始获取该新实例 ID 的详细信息
					fsdata, err := Instanceid_To_Feishudata(insid)
					fmt.Printf("New instance --> ")
					fmt.Println(fsdata)
					if err != nil {
						continue
					}
					if fsdata.email != "" && fsdata.apptype == true && fsdata.prodaccount != "" && fsdata.ssopermissions[0] != "" {
						Wait_Addpermiss_Ins = append(Wait_Addpermiss_Ins, insid)
					}
				}
			}
		}

		//do it every 5 seconds
		timer := time.NewTimer(time.Duration(5) * time.Second)
		// wait
		<-timer.C
	}
}

// 检查是否在三天的删除列表中,如果在三天的删除列表中，则从文档 wait_delete_up.txt 中直接移除,perinfo 38083844xxxxx|xxxxxx@pingcap.com|DBaaS-Prod-OnCall-Role
func Check_Del_three_Days(perinfo string) {
	filepath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Println(err)
	}
	wait_delete_upfile := filepath + `/config/wait_delete_up.txt`
	Lockroute.Lock()
	wait_delstr := Read_txt_File(wait_delete_upfile)
	Lockroute.Unlock()
	perallstr := ""
	if wait_delstr != "" {
		wait_del_spi := strings.Split(wait_delstr, "\n")
		if len(wait_del_spi) >= 1 {
			for _, wait_del_per := range wait_del_spi {
				if strings.Contains(wait_del_per, perinfo) == false {
					perallstr = perallstr + wait_del_per + "\n"
				}
			}
		}
	}
	//重新写入
	Lockroute.Lock()
	WriteData_To_File(wait_delete_upfile, perallstr)
	Lockroute.Unlock()
}

/*
Monitor the Wait_Addpermiss_Ins[] array, if there is an approved and qualified one,
perform the operation of granting permission,
and then remove the fsdata item that has been granted permission
*/
func Monitor_Addper() {
	fmt.Printf("\x1b[%dmStart monitoring new instance id \x1b[0m\n", 37)
	for {
		if len(Wait_Addpermiss_Ins) >= 1 {
			for id, fsinstance := range Wait_Addpermiss_Ins {
				fsdata, err := Instanceid_To_Feishudata(fsinstance)
				if err != nil {
					continue
				}
				if fsdata.isapproved == true { //申请通过才显示
					fmt.Printf("Approved --> ")
					fmt.Println(fsdata)
					/*
						Start adding permissions
					*/

					cloud_type, cerr := Cloud_Paltform_Type(fsinstance) //判断云平台类型 GCP  AWS Alibaba Azure
					if cerr != nil {
						continue
					}

					switch cloud_type {
					case "AWS":
						AWS_Add_Permissions(fsdata.prodaccount, fsdata.email, fsdata.ssopermissions)
						break
					case "GCP":
						GCP_Add_Permissions(fsdata.prodaccount, fsdata.email, fsdata.ssopermissions)
						break
					case "Azure":
						Azure_Add_Permissions(fsdata.prodaccount, fsdata.email, fsdata.ssopermissions)

					case "Alibaba":
						Alibaba_Add_Permissions(fsdata.prodaccount, fsdata.email, fsdata.ssopermissions)
					}

					//After the permission is successfully added, remove the instance ID
					Wait_Addpermiss_Ins = RemoveAtIndex(Wait_Addpermiss_Ins, id)

				}
			}
		}
		//do it every 5 seconds
		timer := time.NewTimer(time.Duration(5) * time.Second)
		// wait
		<-timer.C
	}
}

// 代入 飞书的 instance ID,判断是 AWS 还是 GCP
func Cloud_Paltform_Type(fsinstance string) (string, error) {
	rets := ""

	urls := `https://open.feishu.cn/open-apis/approval/v4/instances/` + strings.TrimSpace(fsinstance)
	//get the token
	APP_Token, aterr := Get_Tenant_AccessToken()
	if aterr != nil {
		return rets, aterr
	}
	InsBody, ierr := HTTP_Req_GET(urls, "Authorization: Bearer "+APP_Token)
	if ierr != nil {
		return rets, ierr
	}

	if strings.Contains(InsBody, `\"GCP Account\"`) == true { // GCP
		rets = "GCP"
	} else if strings.Contains(InsBody, `\"Azure Account\"`) == true { //Azure
		rets = "Azure"
	} else if strings.Contains(InsBody, `\"Alibaba Account\"`) == true { // Alibaba
		rets = "Alibaba"
	} else { // AWS
		rets = "AWS"
	}

	return rets, nil
}

// 判断采用的哪个云平台，返回 AWS、GCP、Azure、Alibaba
func Is_AWS_GCP_Azure_Alibaba(account string) string {
	retstr := ""
	account = strings.TrimSpace(account)
	switch account {
	case "557537366020", "380838443567", "143458967504", "730335266318", "886436949658", "182399704004", "632330501419", "296171618728":
		retstr = "AWS"
		break
	case "tidbcloud-prod-000", "dbaas-prod", "gcp-autonomous-prod", "tidbcloud-auth0", "tidbcloud-test":
		retstr = "GCP"
		break
	case "tidb-dedicated-prod-controlplane", "tidb-dedicated-prod-dataplane-000", "tidb-o11y":
		retstr = "Azure"
		break
	case "5480039859161595", "5108739859105002":
		retstr = "Alibaba"
		break
	}

	return retstr
}

/*
这里是增加 GCP 权限的函数,account 为账号，user 为用户邮箱，perspi 为权限集，这里为数组
最后的 cnemail 为新飞书的邮箱。     2024.10.17 因为新飞书流程迁移回老飞书，cnmail 参数去掉
*/
func GCP_Add_Permissions(account string, user string, perspi []string) {
	if account != "" && user != "" && len(perspi) >= 1 {
		for _, permstr := range perspi { //遍历数组中的每一个权限集
			//开始检查是否包含在 wait_delete_up.txt 中(//现在是在添加权限集之前，还需要检查该权限集是否在3天的移除范围之内)
			chstr := account + "|" + user + "|" + permstr
			Check_Del_three_Days(chstr)
			gerr := gcpsso.GCP_Add_Custom_roles(account, user, perspi)

			if gerr == nil { //权限添加成功后，给申请人员发送消息
				ntime := time.Now().Format("2006-01-02 15:04:05")
				Writelog_To_File("./log/add_permission_log", ntime+" "+account+" "+user+" "+permstr+" add permissions success")
				fmt.Println(ntime + " --> " + account + " " + user + " " + permstr + " add permissions success")
				//发送飞书提醒消息
				send_feishu_message := strings.ReplaceAll(GCP_Add_Permission_notice, "permission_name", permstr)
				fserr := Send_User_Notice(user, "GCP SSO 权限申请反馈通知", send_feishu_message)
				if fserr == nil {
					fmt.Println("send feishu notice message success")
				} else {
					fmt.Println("send feishu notice message failed")
				}

				fmt.Println("")
			} else {
				fmt.Println(gerr)
				continue
			}
		}
	}
}

/*
这里是增加 AWS 权限的函数,account 为账号，user 为用户邮箱，perspi 为权限集，这里为数组
最后的 cnemail 为新飞书的邮箱，因为需要迁移回老飞书，该函数去掉 cnemail cnemail string
*/
func AWS_Add_Permissions(account string, user string, perspi []string) {
	if account != "" && user != "" && len(perspi) >= 1 {
		for _, permstr := range perspi { //遍历数组中的每一个权限集
			//开始检查是否包含在 wait_delete_up.txt 中(//现在是在添加权限集之前，还需要检查该权限集是否在3天的移除范围之内)
			chstr := account + "|" + user + "|" + permstr
			Check_Del_three_Days(chstr)

			//获取用户 ID
			uid, uerr := awssso.Get_User_ID(user)
			if uerr != nil || uid == "" {
				fmt.Println(uerr)
				return
			}

			//获取权限集的 ARN
			per_arn, perr := awssso.Get_Permissions_ARN(permstr)
			if perr != nil {
				fmt.Println(perr)
				return
			}

			//开始添加权限
			var userinfo awssso.Add_Per_User_Info
			userinfo.Account = account
			userinfo.User_id = uid
			userinfo.Permission_set_arn = per_arn
			err := userinfo.Add_Permission_To_Account()
			if err == nil { //权限添加成功后，给申请人员发送消息
				ntime := time.Now().Format("2006-01-02 15:04:05")
				Writelog_To_File("./log/add_permission_log", ntime+" "+account+" "+user+" "+permstr+" add permissions success")
				fmt.Println(ntime + " --> " + account + " " + user + " " + permstr + " add permissions success")
				//发送飞书提醒消息
				send_feishu_message := strings.ReplaceAll(AWS_Add_Permission_notice, "permission_name", permstr)
				fserr := Send_User_Notice(user, "AWS SSO 权限申请反馈通知", send_feishu_message)
				if fserr == nil {
					fmt.Println("send feishu notice message success")
				} else {
					fmt.Println("send feishu notice message failed")
				}

				fmt.Println("")
			} else {
				fmt.Println(err)
				continue
			}
		}
	}
}

/*
Bring the specified subscript into the array,
remove the subscript item brought in, and return the removed array
*/
func RemoveAtIndex(arr []string, index int) []string {
	if index >= len(arr) {
		return arr
	}
	return append(arr[:index], arr[index+1:]...)
}

// 一些日志，这里是追加写入
func Writelog_To_File(FilePathName string, Datastr string) error {
	Datastr = Datastr + "\n"
	f, err := os.OpenFile(FilePathName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		return err
	}

	_, err = f.Write([]byte(Datastr))
	if err != nil {
		return err
	}
	f.Close()
	return nil
}
