package apikey

import (
	"time"

	"github.com/tidbcloud/account/idl/pbgen/proto/central"
	"github.com/tidbcloud/account/internel/dao/entity"
	"google.golang.org/protobuf/types/known/timestamppb"
)

func ConvertKeyEntity2ApiKey(keyEntity *entity.ApiKey, sk string, roleBindings []entity.RoleBinding) *ApiKey {
	unix := time.Unix(keyEntity.CreatedAt.Unix(), 0)
	key := ApiKey{
		Id:            keyEntity.ID.Uint64(),
		AccessKey:     keyEntity.AccessKey,
		SecretKey:     sk,
		Source:        keyEntity.Source,
		Description:   keyEntity.Description,
		CreatedBy:     keyEntity.CreatedBy,
		UpdatedBy:     keyEntity.UpdatedBy,
		CreatedAt:     &unix,
		UpdatedAt:     keyEntity.UpdatedAt,
		ResourceInfos: []*ApiKeyResourceInfo{},
		RateLimitRpm:  keyEntity.RateLimitRpm,
		ExpiredAt:     keyEntity.ExpiredAt,
		BizAttr:       keyEntity.BizAttr,
		Type:          keyEntity.Type,
	}
	if len(roleBindings) > 0 {
		resourceInfos := ConvertRoleBinding2ResourceInfo(int32(len(roleBindings)), roleBindings)
		key.ResourceInfos = resourceInfos.Items
	}

	return &key
}

func ConvertRoleBinding2ResourceInfo(total int32, roleBindings []entity.RoleBinding) *ApiKeyResourceInfos {
	resourceInfos := ApiKeyResourceInfos{
		Total: total,
		Items: []*ApiKeyResourceInfo{},
	}
	for _, dbRoleBinding := range roleBindings {
		resourceInfo := ApiKeyResourceInfo{
			ScopeType:  dbRoleBinding.ScopeType.String(),
			ResourceId: dbRoleBinding.ScopeID.Uint64(),
			Role:       dbRoleBinding.Role,
			RoleId:     dbRoleBinding.RoleID.Uint64(),
		}
		resourceInfos.Items = append(resourceInfos.Items, &resourceInfo)
	}
	return &resourceInfos
}

func ConvertApiKey2CentralApiKey(apiKey *ApiKey) *central.ApiKey {
	key := central.ApiKey{
		Id:            apiKey.Id,
		AccessKey:     apiKey.AccessKey,
		SecretKey:     apiKey.SecretKey,
		Source:        apiKey.Source,
		Description:   apiKey.Description,
		CreatedBy:     apiKey.CreatedBy,
		UpdatedBy:     apiKey.UpdatedBy,
		CreatedAt:     timestamppb.New(*apiKey.CreatedAt),
		UpdatedAt:     timestamppb.New(*apiKey.UpdatedAt),
		ResourceInfos: []*central.ApiKeyResourceInfo{},
	}
	if len(apiKey.ResourceInfos) > 0 {
		for _, resourceInfo := range apiKey.ResourceInfos {
			info := ConvertResourceInfo2CentralResourceInfo(resourceInfo)
			key.ResourceInfos = append(key.ResourceInfos, info)
		}
	}

	return &key
}

func ConvertResourceInfo2CentralResourceInfo(resourceInfo *ApiKeyResourceInfo) *central.ApiKeyResourceInfo {
	return &central.ApiKeyResourceInfo{
		ScopeType:  resourceInfo.ScopeType,
		ResourceId: resourceInfo.ResourceId,
		Role:       resourceInfo.Role,
		RoleId:     resourceInfo.RoleId,
	}
}
