package feishu

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

var Lockroute sync.Locker = &sync.Mutex{}

func Monitor_History_Instance() {
	
	filepath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Println(err)
		return
	}
	deledfile := filepath + `/config/deleted_permission.txt`
	Lockroute.Lock()
	DeledHisid := Read_txt_File(deledfile)
	Lockroute.Unlock()
	fmt.Printf("\x1b[%dmStart monitoring expired granted permission sets \x1b[0m\n", 37)
	for {
		Hins, herr := Get_ALL_Permissions()
		if herr != nil {
			continue
		}
		if Hins != "" {
			hspi := strings.Split(Hins, "\n")
			if len(hspi) >= 1 {
				for _, idstr := range hspi {
					if idstr != "" {
						if strings.Contains(DeledHisid, idstr) == false {
							fsdata, err := Instanceid_To_Feishudata(idstr)
							if err != nil {
								continue
							}
							//fmt.Println(fsdata)
							if fsdata.isovertime == true && fsdata.email != "" && len(fsdata.ssopermissions) >= 1 && fsdata.ssopermissions[0] != "" && fsdata.isapproved == true && fsdata.apptype == true && fsdata.prodaccount != "" {
								cloud_type, cerr := Cloud_Paltform_Type(idstr)
								if cerr != nil {
									continue
								}
								switch cloud_type {
								case "AWS":
									for _, ssoperms := range fsdata.ssopermissions {
										//1、先判断是否满足生产 account 且非安全人员的user,满足返回 true,不满足返回 false
										if Check_Account_User(fsdata.prodaccount, fsdata.email) == true {
											real_permission_name := Convert_Feishu_Permission(ssoperms) //权限集转换
											if real_permission_name != "" {
												ntime := time.Now().Format("2006-01-02 15:04:05")
												//2、时间(格式 2023-07-08 13:52:04) |account|user(email)|permission|cnemail 存入一个文件中，以在 3 天后清理该权限
												//时间|account|email|permissions
												//这里直接调用写日志的函数，因为都是追加写入的
												Lockroute.Lock()
												waitstrs := Read_txt_File(filepath + `/config/wait_delete_up.txt`)
												Lockroute.Unlock()
												if strings.Contains(waitstrs, fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name) == false {
													if real_permission_name == "others" {
														continue
													}

													Lockroute.Lock()
													wserr := Writelog_To_File(filepath+`/config/wait_delete_up.txt`, ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name)
													Lockroute.Unlock()
													if wserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success"+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed\n")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed"+"\x1b[0m\n", 33)
														fmt.Println("")
													}

													//1、发送飞书通知（需要写入日志）
													send_feishu_message := strings.ReplaceAll(AWS_Expired_notice, "permission_name", real_permission_name)
													fserr := Send_User_Notice(fsdata.email, "AWS SSO 权限过期提醒通知", send_feishu_message)
													if fserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message success")
														Lockroute.Unlock()
														tmplog := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message success"
														fmt.Printf("\x1b[%dm"+tmplog+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message failed")
														Lockroute.Unlock()
														tmplogerr := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message failed"
														fmt.Printf("\x1b[%dm"+tmplogerr+"\x1b[0m\n", 33)
													}

												}
												fmt.Println("")
											}
										}
									}
									break
								case "GCP":
									for _, ssoperms := range fsdata.ssopermissions {
										//1、先判断是否满足生产 account 且非安全人员的 user,满足返回 true,不满足返回 false
										if Check_Account_User(fsdata.prodaccount, fsdata.email) == true {
											real_permission_name := strings.TrimSpace(ssoperms)
											if real_permission_name != "" {
												ntime := time.Now().Format("2006-01-02 15:04:05")

												//2、时间(格式 2023-07-08 13:52:04) |account|user(email)|permission|cnemail 存入一个文件中，以在 3 天后清理该权限
												//时间|account|email|permissions
												//这里直接调用写日志的函数，因为都是追加写入的
												Lockroute.Lock()
												waitstrs := Read_txt_File(filepath + `/config/wait_delete_up.txt`)
												Lockroute.Unlock()
												if strings.Contains(waitstrs, fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name) != true {
													Lockroute.Lock()
													wserr := Writelog_To_File(filepath+`/config/wait_delete_up.txt`, ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name)
													Lockroute.Unlock()
													if wserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success"+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed\n")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed"+"\x1b[0m\n", 33)
														fmt.Println("")
													}

													//1、发送飞书通知（需要写入日志）
													send_feishu_message := strings.ReplaceAll(GCP_Expired_notice, "permission_name", real_permission_name)
													fserr := Send_User_Notice(fsdata.email, "GCP SSO 权限过期提醒通知", send_feishu_message)
													if fserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message success")
														Lockroute.Unlock()
														tmplog := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message success"
														fmt.Printf("\x1b[%dm"+tmplog+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message failed")
														Lockroute.Unlock()
														tmplogerr := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message failed"
														fmt.Printf("\x1b[%dm"+tmplogerr+"\x1b[0m\n", 33)
													}

												}
												fmt.Println("")
											}
										}
									}
									break
								case "Azure":
									// 以下代码从  AWS 拷贝，还需要大量修改
									for _, ssoperms := range fsdata.ssopermissions {
										//1、先判断是否满足生产 account 且非安全人员的user,满足返回 true,不满足返回 false
										if Check_Account_User(fsdata.prodaccount, fsdata.email) == true {
											//real_permission_name := Convert_Feishu_Permission(ssoperms) //权限集转换
											real_permission_name := Azure_Convert_Role_Name(fsdata.prodaccount, ssoperms)
											if real_permission_name != "" {
												ntime := time.Now().Format("2006-01-02 15:04:05")
												//2、时间(格式 2023-07-08 13:52:04) |account|user(email)|permission|cnemail 存入一个文件中，以在 3 天后清理该权限
												//时间|account|email|permissions
												//这里直接调用写日志的函数，因为都是追加写入的
												Lockroute.Lock()
												waitstrs := Read_txt_File(filepath + `/config/wait_delete_up.txt`)
												Lockroute.Unlock()
												if strings.Contains(waitstrs, fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name) == false {
													if real_permission_name == "others" {
														continue
													}

													Lockroute.Lock()
													wserr := Writelog_To_File(filepath+`/config/wait_delete_up.txt`, ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name)
													Lockroute.Unlock()
													if wserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success"+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed\n")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed"+"\x1b[0m\n", 33)
														fmt.Println("")
													}

													//1、发送飞书通知（需要写入日志）
													send_feishu_message := strings.ReplaceAll(Azure_Expired_notice, "permission_name", real_permission_name)
													fserr := Send_User_Notice(fsdata.email, "Azure SSO 权限过期提醒通知", send_feishu_message)
													if fserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message success")
														Lockroute.Unlock()
														tmplog := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message success"
														fmt.Printf("\x1b[%dm"+tmplog+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message failed")
														Lockroute.Unlock()
														tmplogerr := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message failed"
														fmt.Printf("\x1b[%dm"+tmplogerr+"\x1b[0m\n", 33)
													}

												}
												fmt.Println("")
											}
										}
									}
									break
								case "Alibaba":
									// 以下代码从 Azure 拷贝，对于 Alibaba 还需要修改
									for _, ssoperms := range fsdata.ssopermissions {
										//1、先判断是否满足生产 account 且非安全人员的user,满足返回 true,不满足返回 false
										if Check_Account_User(fsdata.prodaccount, fsdata.email) == true {
											//real_permission_name := Convert_Feishu_Permission(ssoperms) //权限集转换
											//real_permission_name := Azure_Convert_Role_Name(fsdata.prodaccount, ssoperms)
											real_permission_name := strings.TrimSpace(ssoperms)
											if real_permission_name != "" {
												ntime := time.Now().Format("2006-01-02 15:04:05")
												//2、时间(格式 2023-07-08 13:52:04) |account|user(email)|permission|cnemail 存入一个文件中，以在 3 天后清理该权限
												//时间|account|email|permissions
												//这里直接调用写日志的函数，因为都是追加写入的
												Lockroute.Lock()
												waitstrs := Read_txt_File(filepath + `/config/wait_delete_up.txt`)
												Lockroute.Unlock()
												if strings.Contains(waitstrs, fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name) == false {
													if real_permission_name == "others" {
														continue
													}

													Lockroute.Lock()
													wserr := Writelog_To_File(filepath+`/config/wait_delete_up.txt`, ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name)
													Lockroute.Unlock()
													if wserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up success"+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed\n")
														Lockroute.Unlock()
														fmt.Printf("\x1b[%dm"+ntime+"|"+fsdata.prodaccount+"|"+fsdata.email+"|"+real_permission_name+" write info to wait_delete_up failed"+"\x1b[0m\n", 33)
														fmt.Println("")
													}

													//1、发送飞书通知（需要写入日志）
													send_feishu_message := strings.ReplaceAll(Alibaba_Expired_notice, "permission_name", real_permission_name)
													fserr := Send_User_Notice(fsdata.email, "Alibaba cloud SSO 权限过期提醒通知", send_feishu_message)
													if fserr == nil {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message success")
														Lockroute.Unlock()
														tmplog := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message success"
														fmt.Printf("\x1b[%dm"+tmplog+"\x1b[0m\n", 33)
													} else {
														Lockroute.Lock()
														Writelog_To_File("./log/del_permission_log", ntime+" "+fsdata.prodaccount+" "+fsdata.email+" "+real_permission_name+" Send permission revocation message failed")
														Lockroute.Unlock()
														tmplogerr := ntime + " " + fsdata.prodaccount + " " + fsdata.email + " " + real_permission_name + " Send permission revocation message failed"
														fmt.Printf("\x1b[%dm"+tmplogerr+"\x1b[0m\n", 33)
													}

												}
												fmt.Println("")
											}
										}
									}

									break
								}

								//这个 飞书 instance ID 不会再去监视了
								DeledHisid = DeledHisid + idstr + "\n"
								Lockroute.Lock()
								WriteData_To_File(deledfile, DeledHisid)
								Lockroute.Unlock()
							}
						}
					}
				}
			}
		}

		//检查 mysql 数据库中的非通用权限集,权限到期的移入待删除文件 wait_delete_up.txt 中
		Check_Special_From_Mysql()

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

/*
监控数据库中的非通用权限集是否过期，若有过期的也写入到 wait_delete_up.txt 中（3天后自动删除），格式如下：
2023-09-10 00:26:07|380838443567|zhangbokang@pingcap.com|DBaaS-Prod-OnCall-Role
且需要删除已经过期的权限集条目
*/
func Check_Special_From_Mysql() {
	filepath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Println(err)
		return
	}
	//otime_columns 是过期的权限数组，格式是一个行一个，2023-09-10 00:26:07|380838443567|zhangbokang@pingcap.com|DBaaS-Prod-OnCall-Role|cnemail
	err, otime_columns := awssso.Connect_mysql_query() //etime+"|"+account+"|"+user+"|"+pername
	if err != nil {
		fmt.Println(err)
		return

	}
	if len(otime_columns) >= 1 {
		for _, columns := range otime_columns {
			columns = strings.TrimSpace(columns)
			columns_spi := strings.Split(columns, "|")
			//1、发送飞书通知，需要写入日志
			send_feishu_message := strings.ReplaceAll(AWS_Expired_notice, "permission_name", columns_spi[3])
			fserr := Send_User_Notice(columns_spi[2], "AWS SSO 权限过期提醒通知", send_feishu_message)
			ntime := time.Now().Format("2006-01-02 15:04:05")
			per_info := columns_spi[1] + " " + columns_spi[2] + " " + columns_spi[3]
			if fserr == nil {
				Lockroute.Lock()
				Writelog_To_File("./log/del_permission_log", ntime+" "+per_info+" Send permission revocation message success")
				Lockroute.Unlock()
				tmplog := ntime + " " + per_info + " Send permission revocation message success"
				fmt.Printf("\x1b[%dm"+tmplog+"\x1b[0m\n", 33)
			} else {
				Lockroute.Lock()
				Writelog_To_File("./log/del_permission_log", ntime+" "+per_info+" Send permission revocation message failed")
				Lockroute.Unlock()
				tmplogerr := ntime + " " + per_info + " Send permission revocation message failed"
				fmt.Printf("\x1b[%dm"+tmplogerr+"\x1b[0m\n", 33)
			}

			//2、用户权限数据写入待删除文件中
			Lockroute.Lock()
			wserr := Writelog_To_File(filepath+`/config/wait_delete_up.txt`, columns)
			Lockroute.Unlock()
			if wserr == nil {
				Lockroute.Lock()
				Writelog_To_File("./log/del_permission_log", columns+" write info to wait_delete_up success")
				Lockroute.Unlock()
				fmt.Printf("\x1b[%dm"+columns+" write info to wait_delete_up success"+"\x1b[0m\n", 33)
			} else {
				Lockroute.Lock()
				Writelog_To_File("./log/del_permission_log", columns+" write info to wait_delete_up failed\n")
				Lockroute.Unlock()
				fmt.Printf("\x1b[%dm"+columns+" write info to wait_delete_up failed"+"\x1b[0m\n", 33)
				fmt.Println("")
			}

			//3、移除数据库中已经加入 config/wait_delete_up.txt 中的权限
			awssso.Remove_value_from_mysql(columns_spi[0], columns_spi[1], columns_spi[2], columns_spi[3])
		}
	}
}

/*
监控 wait_delete_up.txt 中的信息，对于到了 3天后的直接移除权限
该函数需要在协程中执行
wait_delete_up 格式 时间(格式 2023-07-08 13:52:04)|account|user(email)|permission_name|cnemail
2024.10.17 流程迁移回老飞书，wait_delete_up 的格式如下：
时间(格式 2023-07-08 13:52:04)|account|user(email)|permission_name
*/
func Monitor_Wait_Delete_up() {
	filepath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		fmt.Println(err)
	}
	wait_delete_upfile := filepath + `/config/wait_delete_up.txt`
	fmt.Printf("\x1b[%dmStart monitoring permission sets removed after 3 days\x1b[0m\n", 37)
	for {
		Lockroute.Lock()
		wait_delstr := Read_txt_File(wait_delete_upfile)
		Lockroute.Unlock()
		newdatas := ""
		if wait_delstr != "" {
			wait_del_spi := strings.Split(wait_delstr, "\n")
			if len(wait_del_spi) >= 1 {
				if wait_del_spi[0] != "" {
					for _, wdsvalues := range wait_del_spi {
						dspi := strings.Split(strings.TrimSpace(wdsvalues), "|")
						if len(dspi) >= 4 {
							timestr := strings.TrimSpace(dspi[0])
							accountstr := strings.TrimSpace(dspi[1])
							email := strings.TrimSpace(dspi[2])
							pername := strings.TrimSpace(dspi[3])
							//cnemail := strings.TrimSpace(dspi[4]) //迁移回老飞书后不再有 cnemail 选项
							//判断 3 天延期是否满足
							if Minus_Time_Day(timestr) == true {
								//判断是 AWS 还是 GCP,true aws，false gcp
								pdstr := Is_AWS_GCP_Azure_Alibaba(accountstr)

								// 处理 AWS 权限
								if pdstr == "AWS" { //AWS
									//开始回收权限
									//获取用户 ID
									uid, uerr := awssso.Get_User_ID(email)
									if uerr != nil || uid == "" {
										fmt.Printf("\x1b[%dm"+"Email convert uid failed["+email+"]"+"\x1b[0m\n", 33)
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", "Email convert uid failed["+email+"]")
										Lockroute.Unlock()
										newdatas = newdatas + wdsvalues + "\n"
										continue
									}

									//获取权限集的 ARN
									per_arn, perr := awssso.Get_Permissions_ARN(pername)
									if perr != nil {
										fmt.Printf("\x1b[%dm"+"Convert pername to perarn failed["+pername+"]"+"\x1b[0m\n", 33)
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", "Convert pername to perarn failed["+pername+"]")
										Lockroute.Unlock()
										newdatas = newdatas + wdsvalues + "\n"
										continue
									}

									var userinfoc awssso.Add_Per_User_Info
									userinfoc.Account = accountstr
									userinfoc.User_id = uid
									userinfoc.Permission_set_arn = per_arn
									err := userinfoc.Remove_Permission_User_Account()
									ntime := time.Now().Format("2006-01-02 15:04:05")
									if err == nil {
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission success")
										Lockroute.Unlock()
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission success"+"\x1b[0m\n", 33)
										//发送飞书消息
										send_feishu_message := strings.ReplaceAll(AWS_Deled_Permission_notice, "permission_name", pername)
										fserr := Send_User_Notice(email, "AWS SSO 权限回收提醒通知", send_feishu_message)
										if fserr == nil { //飞书发送消息成功
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success"+"\x1b[0m\n", 33)
										} else { //飞书发送消息失败
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed"+"\x1b[0m\n", 33)
										}
									} else { //移除 AWS 权限失败
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed")
										Lockroute.Unlock()
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed"+"\x1b[0m\n", 33)
										newdatas = newdatas + wdsvalues + "\n"
									}

								}

								// 处理 GCP 权限
								if pdstr == "GCP" { //GCP
									var gcp_role_spi []string
									gcp_role_spi = append(gcp_role_spi, pername)
									gerr := gcpsso.GCP_Remove_Custom_roles(accountstr, email, gcp_role_spi)
									ntime := time.Now().Format("2006-01-02 15:04:05")
									if gerr == nil {
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission success")
										Lockroute.Unlock()
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission success"+"\x1b[0m\n", 33)
										//发送飞书消息
										send_feishu_message := strings.ReplaceAll(GCP_Deled_Permission_notice, "permission_name", pername)
										fserr := Send_User_Notice(email, "GCP SSO 权限回收提醒通知", send_feishu_message)
										if fserr == nil { //飞书发送消息成功
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success"+"\x1b[0m\n", 33)
										} else { //飞书发送消息失败
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed"+"\x1b[0m\n", 33)
										}
									} else { //移除 GCP 权限失败
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed: "+gerr.Error())
										Lockroute.Unlock()
										newdatas = newdatas + wdsvalues + "\n"
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed: "+gerr.Error()+"\x1b[0m\n", 33)
									}
								}

								// 处理 Azure 权限
								if pdstr == "Azure" {
									//var gcp_role_spi []string
									//gcp_role_spi = append(gcp_role_spi, pername)

									subscription_id := Azure_Convert_subid(accountstr)
									role_name_real := strings.TrimSpace(pername)
									/*
										if accountstr == "tidb-dedicated-prod-dataplane-000" {
											role_name_real = pername + "-0"
										}
										if accountstr == "tidb-o11y" {
											role_name_real = pername + "-o11y"
										}
										if accountstr == "tidb-dedicated-prod-controlplane" {
											role_name_real = pername
										}
									*/

									aerr := Azure_RemoveRole(email, role_name_real, subscription_id)

									ntime := time.Now().Format("2006-01-02 15:04:05")
									if aerr == nil { // 移除 Azure 权限成功
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission success")
										Lockroute.Unlock()
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission success"+"\x1b[0m\n", 33)
										//发送飞书消息
										send_feishu_message := strings.ReplaceAll(Azure_Deled_Permission_notice, "permission_name", pername)
										fserr := Send_User_Notice(email, "Azure SSO 权限回收提醒通知", send_feishu_message)
										if fserr == nil { //飞书发送消息成功
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success"+"\x1b[0m\n", 33)
										} else { //飞书发送消息失败
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed"+"\x1b[0m\n", 33)
										}
									} else { //移除 Azure 权限失败
										Lockroute.Lock()
										fmt.Println(aerr.Error())
										fmt.Println(email + "|" + role_name_real + "|" + accountstr + "|" + subscription_id)
										fmt.Println("")
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed")
										Lockroute.Unlock()
										newdatas = newdatas + wdsvalues + "\n"
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed"+"\x1b[0m\n", 33)
									}
								}

								if pdstr == "Alibaba" {
									alierr := Alibaba_Delete_Permissions(accountstr, email, pername)
									ntime := time.Now().Format("2006-01-02 15:04:05")
									if alierr == nil { // 移除 Azure 权限成功
										Lockroute.Lock()
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission success")
										Lockroute.Unlock()
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission success"+"\x1b[0m\n", 33)
										//发送飞书消息
										send_feishu_message := strings.ReplaceAll(Alibaba_Deled_Permission_notice, "permission_name", pername)
										fserr := Send_User_Notice(email, "Alibaba Cloud SSO 权限回收提醒通知", send_feishu_message)
										if fserr == nil { //飞书发送消息成功
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message success"+"\x1b[0m\n", 33)
										} else { //飞书发送消息失败
											Lockroute.Lock()
											Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed")
											Lockroute.Unlock()
											fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" send feishu message failed"+"\x1b[0m\n", 33)
										}
									} else { //移除 alibnba cloud 权限失败
										Lockroute.Lock()
										fmt.Println(alierr.Error())
										fmt.Println(email + "|" + pername + "|" + accountstr)
										fmt.Println("")
										Writelog_To_File("./log/del_permission_log", ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed")
										Lockroute.Unlock()
										newdatas = newdatas + wdsvalues + "\n"
										fmt.Printf("\x1b[%dm"+ntime+" "+accountstr+" "+email+" "+pername+" remove permission failed"+"\x1b[0m\n", 33)
									}
								}

							} else { // 3 天时间未到,newdatas 覆盖的写入 wait_delete_upfile 中
								newdatas = newdatas + wdsvalues + "\n"
							}
						}
					}
				}

			}
		}
		//newdatas 重新写入 wait_delete_upfile 中（这里保存的是还未到期的）
		Lockroute.Lock()
		WriteData_To_File(wait_delete_upfile, newdatas)
		Lockroute.Unlock()

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

/*
因为飞书之前的权限集和真实的权限集对应不上，所以需要该函数转换成真实的权限集
*/
func Convert_Feishu_Permission(permission_name string) string {
	permission_name = strings.TrimSpace(permission_name)
	permission_name = strings.ToLower(permission_name)
	if strings.Contains(permission_name, "viewonly") == true {
		return "DBaaS-Prod-ViewOnly-Role"
	}

	if strings.Contains(permission_name, "oncall") == true {
		if strings.Contains(permission_name, "bastionec2") == true {
			return "BaaS-Prod-OnCall-BastionEC2-Role"
		} else {
			return "DBaaS-Prod-OnCall-Role"
		}
	}

	if strings.Contains(permission_name, "billing") == true {
		return "DBaaS-Prod-Billing-Role"
	}

	if strings.Contains(permission_name, "prod-admin") == true {
		return "DBaaS-Prod-Admin-Role"
	}

	if strings.Contains(permission_name, "security") == true {
		return "PingCAP-SecurityAdmin-Role"
	}

	if strings.Contains(permission_name, "prod-ec2") == true {
		return "DBaaS-Prod-EC2-Role"
	}

	if strings.Contains(permission_name, "devuser") == true {
		return "DBaaS-DevUser-Role"
	}

	if strings.Contains(permission_name, "prod-web") == true {
		return "DBaaS-Prod-Web-Role"
	}

	if strings.Contains(permission_name, "orgoperator") == true {
		return "DBaaS-Prod-OrgOperator-Role"
	}

	if strings.Contains(permission_name, "tiflow-engine-rds") == true {
		return "Prod-Tiflow-Engine-RDS"
	}

	if strings.Contains(permission_name, "devleader") == true {
		return "DBaaS-DevLeader-Role"
	}

	if strings.Contains(permission_name, "prod-support-role") == true {
		return "DBaaS-Prod-Support-Role"
	}

	return strings.TrimSpace(permission_name)
}

/*
Azure 的权限，按照订阅的不同，实际的 role 权限名称需要转换

1、tidb-dedicated-prod-controlplane

	role=role

2、tidb-dedicated-prod-dataplane-000

	DBaaS-Prod-Admin-Role-0
	role=role + "-0"

3、tidb-o11y

	DBaaS-Prod-DevAdmin-Role-o11y
	role = role + "-o11y"
*/
func Azure_Convert_Role_Name(subscription string, permission_name string) string {
	retstr := ""
	subscription = strings.TrimSpace(subscription)
	switch subscription {
	case "tidb-dedicated-prod-controlplane":
		retstr = strings.TrimSpace(permission_name)
		break
	case "tidb-dedicated-prod-dataplane-000":
		retstr = strings.TrimSpace(permission_name) + "-0"
		break
	case "tidb-o11y":
		retstr = strings.TrimSpace(permission_name) + "-o11y"
		break
	}
	return retstr
}

/*
回收权限时，限定账号和 user 白名单函数，满足以下两个条件返回 true，否则 false(报错也返回false)
1、回收权限的 account 在限定的 4 个生产账号内
2、user 的 email 排除在白名单外
*/
func Check_Account_User(account string, user string) bool {
	account = strings.TrimSpace(account)
	user = strings.TrimSpace(user)
	// read limit_account.txt
	filepath, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		return false
	}
	//check limit account
	limit_account_file := filepath + `/config/limit_account.txt`
	limit_accounts := Read_txt_File(limit_account_file)
	limit_accounts_spi := strings.Split(limit_accounts, "\n")
	var pd_account bool = false
	if len(limit_accounts_spi) >= 1 {
		for _, eat := range limit_accounts_spi {
			eat = strings.TrimSpace(eat)
			if eat == account {
				pd_account = true
				break
			}
		}
	} else {
		return false
	}
	if pd_account == false { //其它账号，不满足，返回 false
		return false
	}

	//check user email,exclude white email
	white_email_file := filepath + `/config/white_email.txt`
	white_emails := Read_txt_File(white_email_file)
	white_emails_spi := strings.Split(white_emails, "\n")
	var pd_user bool = true
	if len(white_emails_spi) >= 1 {
		for _, wems := range white_emails_spi {
			wems = strings.TrimSpace(wems)
			if wems == user {
				pd_user = false
				break
			}
		}
	} else {
		return false
	}
	if pd_user == false {
		return false
	}
	return true
}

/*
open-apis/approval/v4/instances?approval_code=81762D1E-68FE-4448-89C4-5F14288778C8&end_time=1686029257000&start_time=1672502400000
*/
func Get_ALL_Permissions() (string, error) {
	var RetIds string
	dirs, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		return "", err
	}
	dirs = dirs + `/config/start_time.txt`
	start_time := Read_txt_File(dirs)
	start_time = strings.ReplaceAll(start_time, "\n", "")
	start_time = strings.TrimSpace(start_time)

	now_time, _, err := GetTimeStamps()
	if err != nil {
		return "", err
	}

	//get the token
	APP_Token, aterr := Get_Tenant_AccessToken()
	if aterr != nil {
		fmt.Println(aterr)
		return "", err
	}

	urls := `https://open.feishu.cn/open-apis/approval/v4/instances?approval_code=` + approval_code + `&end_time=` + now_time + `&page_size=100&start_time=` + start_time
	InsBody, err := HTTP_Req_GET(urls, "Authorization: Bearer "+APP_Token)
	if err != nil {
		return "", nil
	}

	InsID, _ := RegxStr(InsBody, Regx_InstancesID)
	RetIds = RetIds + InsID + "\n"

	page_token, _ := RegxStr(InsBody, `"page_token":"[\w\=]+"\}`)
	for {
		if page_token != "" {
			page_token = strings.ReplaceAll(page_token, `"page_token":"`, "")
			page_token = strings.ReplaceAll(page_token, `"}`, "")
			//fmt.Println(urls + "&page_token=" + page_token)
			InsBody, err = HTTP_Req_GET(urls+"&page_token="+page_token, "Authorization: Bearer "+APP_Token)
			if err != nil {
				return "", err
			}
			InsID, _ = RegxStr(InsBody, Regx_InstancesID)
			RetIds = RetIds + InsID + "\n"

			page_token, _ = RegxStr(InsBody, `"page_token":"[\w\=]+"\}`)
			page_token = strings.ReplaceAll(page_token, `"page_token":"`, "")
			page_token = strings.ReplaceAll(page_token, `"}`, "")
		} else {
			break
		}
	}
	RetIds = strings.TrimRight(RetIds, "\n")
	//fmt.Println(RetIds)
	return RetIds, nil
}

/*
判断当前时间和代入的时间差值是否超过3天，如果超过 3 天则返回true
past_time 的格式为类似 2023-07-08 13:52:04
*/
func Minus_Time_Day(past_time string) bool {
	past_time = strings.TrimSpace(past_time)
	now_time := time.Now().Format("2006-01-02 15:04:05")
	// 将时间字符串解析为time.Time类型
	layout := "2006-01-02 15:04:05"
	pt, _ := time.Parse(layout, past_time)
	nt, _ := time.Parse(layout, now_time)

	// 计算两个时间的差值
	diff := nt.Sub(pt).Hours()

	// 判断差值是否大于3天
	dayDiff := int(diff / 24)
	result := dayDiff >= 3
	return result
}
