package alicloud

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/spf13/viper"
	"strings"

	cloudsso20210515 "github.com/alibabacloud-go/cloudsso-20210515/client"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	"github.com/aliyun/credentials-go/credentials"
	"github.com/pingcap-inc/pchub/pkg/log"
)

func CreateClient(c context.Context) (_result *cloudsso20210515.Client, _err error) {
	log.L(c).Info("Creating AliCloud STS client...")

	ak := viper.GetString("access_key_id")
	sk := viper.GetString("access_key_secret")
	stsToken, err := GenerateStsToken(c, ak, sk)
	if err != nil {
		log.L(c).Errorf("Failed to generate STS token: %v", err)

		return nil, err
	}
	config := new(credentials.Config).
		SetType("sts").
		SetAccessKeyId(ak).
		SetAccessKeySecret(sk).
		SetSecurityToken(*stsToken)

	stsCredential, _err := credentials.NewCredential(config)
	if _err != nil {
		return _result, _err
	}

	cf := &openapi.Config{}
	cf.Credential = stsCredential
	// Endpoint 请参考 https://api.aliyun.com/product/cloudsso
	cf.Endpoint = tea.String("cloudsso.cn-shanghai.aliyuncs.com")
	_result = &cloudsso20210515.Client{}
	_result, _err = cloudsso20210515.NewClient(cf)
	return _result, _err
}

func AliCloudAssumeRole(c context.Context) error {
	client, _err := CreateClient(c)
	if _err != nil {
		log.L(c).Errorf("Failed to create AliCloud client: %v", _err)

		return _err
	}

	directoryId := viper.GetString("alicloud.directory_id")
	accessConfigurationId := viper.GetString("alicloud.access_configuration_id")

	listPermissionPoliciesInAccessConfigurationRequest := &cloudsso20210515.CreateAccessAssignmentRequest{
		DirectoryId:           tea.String(directoryId),
		AccessConfigurationId: tea.String(accessConfigurationId),
		PrincipalId:           tea.String(""),
		PrincipalType:         tea.String("USER"),
		TargetId:              tea.String(""),
		TargetType:            tea.String("ACCOUNT"),
	}

	_, _err = client.CreateAccessAssignmentWithOptions(listPermissionPoliciesInAccessConfigurationRequest, &util.RuntimeOptions{})

	if _err != nil {
		var error = &tea.SDKError{}
		if _t, ok := _err.(*tea.SDKError); ok {
			error = _t
		} else {
			error.Message = tea.String(_err.Error())
		}
		// 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
		// 错误 message
		fmt.Println(tea.StringValue(error.Message))
		// 诊断地址
		var data interface{}
		d := json.NewDecoder(strings.NewReader(tea.StringValue(error.Data)))
		d.Decode(&data)
		if m, ok := data.(map[string]interface{}); ok {
			recommend, _ := m["Recommend"]
			fmt.Println(recommend)
		}
		_, _err = util.AssertAsString(error.Message)
		if _err != nil {
			log.L(c).Errorf("AliCloudAssumeRole error: %v", _err)

			return _err
		}
	}

	log.L(c).Info("AliCloud assume role successfully")

	return nil
}
