package cloud

import (
	"context"
	"fmt"

	"github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/alicloud"
	"github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/aws"
	"github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/azure"
	"github.com/pingcap-inc/pchub/internal/apiserver/service/v1/cloud/gcp"
	modelv1 "github.com/pingcap-inc/pchub/model/v1"
)

// Factory 云平台工厂
type Factory struct{}

// NewFactory 创建工厂实例
func NewFactory() *Factory {
	return &Factory{}
}

// CreateProvider 创建云平台提供者
func (f *Factory) CreateProvider(providerCode string) (CloudProvider, error) {
	switch providerCode {
	case "azure", "azurecn":
		provider, err := azure.NewProvider()
		if err != nil {
			return nil, fmt.Errorf("failed to create Azure provider: %w", err)
		}
		return &azureProvider{provider: provider}, nil
	case "aws":
		provider, err := aws.NewProvider()
		if err != nil {
			return nil, fmt.Errorf("failed to create AWS provider: %w", err)
		}
		return &awsProvider{provider: provider}, nil
	case "gcp":
		provider, err := gcp.NewProvider()
		if err != nil {
			return nil, fmt.Errorf("failed to create GCP provider: %w", err)
		}
		return &gcpProvider{provider: provider}, nil
	case "alicloud", "alibaba":
		provider, err := alicloud.NewProvider()
		if err != nil {
			return nil, fmt.Errorf("failed to create Alibaba Cloud provider: %w", err)
		}
		return &alicloudProvider{provider: provider}, nil
	default:
		return nil, fmt.Errorf("unsupported cloud provider: %s", providerCode)
	}
}

// azureProvider Azure提供者适配器
type azureProvider struct {
	provider *azure.Provider
}

func (ap *azureProvider) SyncUserRoles(ctx context.Context, roles []*modelv1.RoleMembers, cloudResource *modelv1.CloudResource, optionType int) error {
	return ap.provider.SyncUserRoles(ctx, roles, cloudResource, optionType)
}

func (ap *azureProvider) GetProviderMembers(ctx context.Context, provider string) ([]modelv1.ResourceMemberAccess, []uint64, error) {
	return ap.provider.GetProviderMembers(ctx, provider)
}

func (ap *azureProvider) GetProviderName() string {
	return ap.provider.GetProviderName()
}

func (ap *azureProvider) ValidateConfig() error {
	return ap.provider.ValidateConfig()
}

func (ap *azureProvider) SyncUsers(ctx context.Context) error {
	return ap.provider.SyncUsers(ctx)
}

func (ap *azureProvider) SyncMembers(ctx context.Context) error {
	return ap.provider.SyncMembers(ctx)
}

// awsProvider AWS提供者适配器
type awsProvider struct {
	provider *aws.Provider
}

func (ap *awsProvider) SyncUserRoles(ctx context.Context, roles []*modelv1.RoleMembers, cloudResource *modelv1.CloudResource, optionType int) error {
	return ap.provider.SyncUserRoles(ctx, roles, cloudResource, optionType)
}

func (ap *awsProvider) GetProviderMembers(ctx context.Context, provider string) ([]modelv1.ResourceMemberAccess, []uint64, error) {
	return ap.provider.GetProviderMembers(ctx, provider)
}

func (ap *awsProvider) GetProviderName() string {
	return ap.provider.GetProviderName()
}

func (ap *awsProvider) ValidateConfig() error {
	return ap.provider.ValidateConfig()
}

func (ap *awsProvider) SyncUsers(ctx context.Context) error {
	return ap.provider.SyncUsers(ctx)
}

func (ap *awsProvider) SyncMembers(ctx context.Context) error {
	return ap.provider.SyncMembers(ctx)
}

// gcpProvider GCP提供者适配器
type gcpProvider struct {
	provider *gcp.Provider
}

func (gp *gcpProvider) SyncUserRoles(ctx context.Context, roles []*modelv1.RoleMembers, cloudResource *modelv1.CloudResource, optionType int) error {
	return gp.provider.SyncUserRoles(ctx, roles, cloudResource, optionType)
}

func (gp *gcpProvider) GetProviderMembers(ctx context.Context, provider string) ([]modelv1.ResourceMemberAccess, []uint64, error) {
	return gp.provider.GetProviderMembers(ctx, provider)
}

func (gp *gcpProvider) GetProviderName() string {
	return gp.provider.GetProviderName()
}

func (gp *gcpProvider) ValidateConfig() error {
	return gp.provider.ValidateConfig()
}

func (gp *gcpProvider) SyncUsers(ctx context.Context) error {
	return gp.provider.SyncUsers(ctx)
}

func (gp *gcpProvider) SyncMembers(ctx context.Context) error {
	return gp.provider.SyncMembers(ctx)
}

// alicloudProvider 阿里云提供者适配器
type alicloudProvider struct {
	provider *alicloud.Provider
}

func (ap *alicloudProvider) SyncUserRoles(ctx context.Context, roles []*modelv1.RoleMembers, cloudResource *modelv1.CloudResource, optionType int) error {
	return ap.provider.SyncUserRoles(ctx, roles, cloudResource, optionType)
}

func (ap *alicloudProvider) GetProviderMembers(ctx context.Context, provider string) ([]modelv1.ResourceMemberAccess, []uint64, error) {
	return ap.provider.GetProviderMembers(ctx, provider)
}

func (ap *alicloudProvider) GetProviderName() string {
	return ap.provider.GetProviderName()
}

func (ap *alicloudProvider) ValidateConfig() error {
	return ap.provider.ValidateConfig()
}

func (ap *alicloudProvider) SyncUsers(ctx context.Context) error {
	return ap.provider.SyncUsers(ctx)
}

func (ap *alicloudProvider) SyncMembers(ctx context.Context) error {
	return ap.provider.SyncMembers(ctx)
}
