package gcpsso

import (
	"context"
	"fmt"
	"google.golang.org/api/cloudresourcemanager/v3"
	"google.golang.org/api/option"
)

const (
	// test environment
	tidbcloud_test_json = "./config/tidbcloud-test.json"

	// product environment
	tidbcloud_prod_000_json  = "./config/tidbcloud-prod-000.json"
	dbaas_prod_json          = "./config/dbaas-prod.json"
	gcp_autonomous_prod_json = "./config/gcp-autonomous-prod.json"
	tidbcloud_auth0_json     = "./config/tidbcloud-auth0.json"

	// user json
	gcp_user_json = `./config/user.json`
)

type GCP_User_Info struct {
	project  string //项目 ID
	username string //用户名邮箱
	rolename string //custom role name 或者 gcp 托管 role
	//Authentication_json string //鉴权json
}

// 实际调用该函数来添加权限
func GCP_Add_Custom_roles(account string, user string, roles []string) error {
	var uinfo GCP_User_Info
	uinfo.project = account
	uinfo.username = user
	for _, role := range roles {
		uinfo.rolename = role
		err := uinfo.GCP_add_custom_role()
		if err != nil {
			return err
		}
	}
	return nil
}

// 实际调用该函数来移除权限
func GCP_Remove_Custom_roles(account string, user string, roles []string) error {
	var uinfo GCP_User_Info
	uinfo.project = account
	uinfo.username = user
	for _, role := range roles {
		uinfo.rolename = role
		err := uinfo.GCP_remove_custom_role()
		if err != nil {
			return err
		}
	}
	return nil
}

func GCP_TEST() {

	var pinfo GCP_User_Info
	pinfo.project = "tidbcloud-test"
	pinfo.username = "dong.zhang@pingcap.com"
	pinfo.rolename = "DBaaS-Prod-Security-Role"

	//pinfo.GCP_add_role_user()
	//err := pinfo.GCP_add_custom_role()
	err := pinfo.GCP_remove_custom_role()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Successfully")
	}

}

// 指定 project 下指定用户 绑定指定的 gcp custom role,这里的 userinfo 中带入 custom role 名称
func (userinfo GCP_User_Info) GCP_add_custom_role() error {
	var ret_err error = nil

	errs, gcp_manage_roles := Read_ini_value(userinfo.rolename)
	if errs != nil {
		return errs
	}
	uinfo := userinfo
	for _, gcp_manage_role := range gcp_manage_roles {
		uinfo.rolename = gcp_manage_role
		er := uinfo.GCP_add_role_user()
		if er != nil {
			ret_err = er
		}
	}

	return ret_err

}

// 移除绑定 gcp custom role,这里的 userinfo 中带入 custom role 名称
func (userinfo GCP_User_Info) GCP_remove_custom_role() error {
	var ret_err error = nil

	errs, gcp_manage_roles := Read_ini_value(userinfo.rolename)
	if errs != nil {
		return errs
	}
	uinfo := userinfo
	for _, gcp_manage_role := range gcp_manage_roles {
		uinfo.rolename = gcp_manage_role
		er := uinfo.GCP_remove_role_user()
		if er != nil {
			ret_err = er
		}
	}

	return ret_err
}

func GCP_add_role_user_ini(gcp_account string, gcp_user string, gcp_role string) error {
	var userinfo GCP_User_Info
	userinfo.project = gcp_account
	userinfo.username = gcp_user
	userinfo.rolename = gcp_role
	err := userinfo.GCP_add_role_user()
	return err
}

func (userinfo GCP_User_Info) GCP_add_role_user() error {
	// 读取服务账户 JSON 密钥文件的路径
	credentialsFile := gcp_user_json

	// 设置 GCP 项目 ID 和要添加角色的用户邮箱
	projectID := userinfo.project
	userEmail := userinfo.username
	role := userinfo.rolename

	ctx := context.Background()

	// 使用服务账户 JSON 鉴权
	client, err := cloudresourcemanager.NewService(ctx, option.WithCredentialsFile(credentialsFile))
	if err != nil {
		return err
	}

	// 获取项目的 IAM 策略
	req := &cloudresourcemanager.GetIamPolicyRequest{}
	policy, err := client.Projects.GetIamPolicy("projects/"+projectID, req).Context(ctx).Do()
	if err != nil {
		return err
	}

	// 创建一个新的绑定，并将其添加到 IAM 策略中
	binding := &cloudresourcemanager.Binding{
		Members: []string{
			fmt.Sprintf("user:%s", userEmail),
		},
		Role: role,
	}

	// 检查是否已存在绑定
	var exists bool
	for _, b := range policy.Bindings {
		if b.Role == role {
			b.Members = append(b.Members, fmt.Sprintf("user:%s", userEmail))
			exists = true
			break
		}
	}

	if !exists {
		policy.Bindings = append(policy.Bindings, binding)
	}

	// 设置更新后的 IAM 策略
	setReq := &cloudresourcemanager.SetIamPolicyRequest{
		Policy: policy,
	}
	_, err = client.Projects.SetIamPolicy("projects/"+projectID, setReq).Context(ctx).Do()
	if err != nil {
		return err
	}

	return nil
}

func GCP_del_role_user_ini(gcp_account string, gcp_user string, gcp_role string) error {
	var userinfo GCP_User_Info
	userinfo.project = gcp_account
	userinfo.username = gcp_user
	userinfo.rolename = gcp_role
	err := userinfo.GCP_remove_role_user()
	return err
}

// 移除权限
func (userinfo GCP_User_Info) GCP_remove_role_user() error {
	credentialsFile := gcp_user_json // 修改为相应的 JSON 文件路径

	projectID := userinfo.project
	userEmail := userinfo.username
	role := userinfo.rolename

	ctx := context.Background()

	client, err := cloudresourcemanager.NewService(ctx, option.WithCredentialsFile(credentialsFile))
	if err != nil {
		return err
	}

	req := &cloudresourcemanager.GetIamPolicyRequest{}
	policy, err := client.Projects.GetIamPolicy("projects/"+projectID, req).Context(ctx).Do()
	if err != nil {
		return err
	}

	for i, b := range policy.Bindings {
		if b.Role == role {
			for j, member := range b.Members {
				if member == fmt.Sprintf("user:%s", userEmail) {
					// 移除成员
					policy.Bindings[i].Members = append(b.Members[:j], b.Members[j+1:]...)
					break
				}
			}
			// 如果这个角色没有其他成员，移除这个绑定
			if len(policy.Bindings[i].Members) == 0 {
				policy.Bindings = append(policy.Bindings[:i], policy.Bindings[i+1:]...)
			}
			break
		}
	}

	setReq := &cloudresourcemanager.SetIamPolicyRequest{
		Policy: policy,
	}
	_, err = client.Projects.SetIamPolicy("projects/"+projectID, setReq).Context(ctx).Do()
	if err != nil {
		return err
	}
	return nil
}
