package cloudstorage

import (
	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/infra/repoimpl/schema"
)

func SchemaToProto(m *schema.CloudStorage) *globalngv1.CloudStorage {
	if m == nil {
		return nil
	}
	out := &globalngv1.CloudStorage{
		Type: globalngv1.CloudStorageType_Enum(globalngv1.CloudStorageType_Enum_value[m.Type]),
	}
	switch out.Type {
	case globalngv1.CloudStorageType_S3:
		out.Storage = &globalngv1.CloudStorage_S3{S3: schemaS3CloudStorageToProto(m.S3)}
	case globalngv1.CloudStorageType_GCS:
		out.Storage = &globalngv1.CloudStorage_Gcs{Gcs: schemaGCSCloudStorageToProto(m.Gcs)}
	case globalngv1.CloudStorageType_AZURE_BLOB:
		out.Storage = &globalngv1.CloudStorage_AzureBlob{AzureBlob: schemaAzureBlobCloudStorageToProto(m.AzureBlob)}
	case globalngv1.CloudStorageType_OSS:
		out.Storage = &globalngv1.CloudStorage_Oss{Oss: schemaOSSCloudStorageToProto(m.Oss)}
	}
	return out
}

func schemaS3CloudStorageToProto(m *schema.S3CloudStorage) *globalngv1.S3CloudStorage {
	if m == nil {
		return nil
	}
	out := &globalngv1.S3CloudStorage{
		Uri:      m.Uri,
		AuthType: globalngv1.S3CloudStorage_S3AuthType(globalngv1.S3CloudStorage_S3AuthType_value[m.AuthType]),
	}
	if m.AccessKey != nil {
		out.Auth = &globalngv1.S3CloudStorage_AccessKey_{
			AccessKey: &globalngv1.S3CloudStorage_AccessKey{
				Id: m.AccessKey.Id,
			},
		}
	} else if m.RoleArn != "" {
		out.Auth = &globalngv1.S3CloudStorage_RoleArn{RoleArn: m.RoleArn}
	}
	return out
}

func schemaGCSCloudStorageToProto(m *schema.GCSCloudStorage) *globalngv1.GCSCloudStorage {
	if m == nil {
		return nil
	}
	out := &globalngv1.GCSCloudStorage{
		Uri:      m.Uri,
		AuthType: globalngv1.GCSCloudStorage_GCSAuthType(globalngv1.GCSCloudStorage_GCSAuthType_value[m.AuthType]),
	}
	return out
}

func schemaAzureBlobCloudStorageToProto(m *schema.AzureBlobCloudStorage) *globalngv1.AzureBlobCloudStorage {
	if m == nil {
		return nil
	}
	out := &globalngv1.AzureBlobCloudStorage{
		Uri:      m.Uri,
		AuthType: globalngv1.AzureBlobCloudStorage_AzureBlobAuthType(globalngv1.AzureBlobCloudStorage_AzureBlobAuthType_value[m.AuthType]),
	}
	return out
}

func schemaOSSCloudStorageToProto(m *schema.OSSCloudStorage) *globalngv1.OSSCloudStorage {
	if m == nil {
		return nil
	}
	out := &globalngv1.OSSCloudStorage{
		Uri:      m.Uri,
		AuthType: globalngv1.OSSCloudStorage_OSSAuthType(globalngv1.OSSCloudStorage_OSSAuthType_value[m.AuthType]),
	}
	if m.AccessKey != nil {
		out.Auth = &globalngv1.OSSCloudStorage_AccessKey_{
			AccessKey: &globalngv1.OSSCloudStorage_AccessKey{
				Id: m.AccessKey.Id,
			},
		}
	} else if m.RoleArn != "" {
		out.Auth = &globalngv1.OSSCloudStorage_RoleArn{RoleArn: m.RoleArn}
	}
	return out
}

func ProtoToSchema(cs *globalngv1.CloudStorage) *schema.CloudStorage {
	if cs == nil {
		return nil
	}
	out := &schema.CloudStorage{
		Type: cs.GetType().String(),
	}
	switch cs.GetType() {
	case globalngv1.CloudStorageType_S3:
		out.S3 = protoS3CloudStorageToSchema(cs.GetS3())
	case globalngv1.CloudStorageType_GCS:
		out.Gcs = protoGCSCloudStorageToSchema(cs.GetGcs())
	case globalngv1.CloudStorageType_AZURE_BLOB:
		out.AzureBlob = protoAzureBlobCloudStorageToSchema(cs.GetAzureBlob())
	case globalngv1.CloudStorageType_OSS:
		out.Oss = protoOSSCloudStorageToSchema(cs.GetOss())
	}
	return out
}

func protoS3CloudStorageToSchema(s *globalngv1.S3CloudStorage) *schema.S3CloudStorage {
	if s == nil {
		return nil
	}
	out := &schema.S3CloudStorage{
		Uri:      s.GetUri(),
		AuthType: s.GetAuthType().String(),
	}
	switch s.GetAuthType() {
	case globalngv1.S3CloudStorage_ACCESS_KEY:
		out.AccessKey = &schema.S3AccessKey{
			Id:     s.GetAccessKey().GetId(),
			Secret: s.GetAccessKey().GetSecret(),
		}
	case globalngv1.S3CloudStorage_ROLE_ARN:
		out.RoleArn = s.GetRoleArn()
	}
	return out
}

func protoGCSCloudStorageToSchema(s *globalngv1.GCSCloudStorage) *schema.GCSCloudStorage {
	if s == nil {
		return nil
	}
	out := &schema.GCSCloudStorage{
		Uri:               s.GetUri(),
		AuthType:          s.GetAuthType().String(),
		ServiceAccountKey: s.GetServiceAccountKey(),
	}
	return out
}

func protoAzureBlobCloudStorageToSchema(s *globalngv1.AzureBlobCloudStorage) *schema.AzureBlobCloudStorage {
	if s == nil {
		return nil
	}
	out := &schema.AzureBlobCloudStorage{
		Uri:      s.GetUri(),
		AuthType: s.GetAuthType().String(),
		SasToken: s.GetSasToken(),
	}
	return out
}

func protoOSSCloudStorageToSchema(s *globalngv1.OSSCloudStorage) *schema.OSSCloudStorage {
	if s == nil {
		return nil
	}
	out := &schema.OSSCloudStorage{
		Uri:      s.GetUri(),
		AuthType: s.GetAuthType().String(),
	}
	switch s.GetAuthType() {
	case globalngv1.OSSCloudStorage_ACCESS_KEY:
		out.AccessKey = &schema.OSSAccessKey{
			Id:     s.GetAccessKey().GetId(),
			Secret: s.GetAccessKey().GetSecret(),
		}
	case globalngv1.OSSCloudStorage_ROLE_ARN:
		out.RoleArn = s.GetRoleArn()
	}
	return out
}
