package types

import (
	"fmt"

	"gitlink.org.cn/cloudream/common/pkgs/types"
	"gitlink.org.cn/cloudream/common/utils/serder"
)

type Storage struct {
	StorageID StorageID `json:"storageID" gorm:"column:StorageID; primaryKey; type:bigint; autoIncrement;"`
	Name      string    `json:"name" gorm:"column:Name; type:varchar(256); not null"`
	// 完全管理此存储服务的Hub的ID
	MasterHub HubID `json:"masterHub" gorm:"column:MasterHub; type:bigint; not null"`
	// 存储服务的类型，包含地址信息以及鉴权所需数据
	Type StorageType `json:"type" gorm:"column:Type; type:json; not null; serializer:union"`
	// 存储服务拥有的特别功能
	Features []StorageFeature `json:"features" gorm:"column:Features; type:json; serializer:union"`
}

func (Storage) TableName() string {
	return "Storage"
}

func (s *Storage) String() string {
	return fmt.Sprintf("%v(%v)", s.Name, s.StorageID)
}

type StorageDetail struct {
	Storage   Storage
	MasterHub *Hub
}

// 存储服务地址
type StorageType interface {
	GetStorageType() string
	// 输出调试用的字符串，不要包含敏感信息
	String() string
}

var _ = serder.UseTypeUnionInternallyTagged(types.Ref(types.NewTypeUnion[StorageType](
	(*MashupStorageType)(nil),
	(*LocalStorageType)(nil),
	(*OBSType)(nil),
	(*OSSType)(nil),
	(*COSType)(nil),
	(*EFileType)(nil),
	(*S3Type)(nil),
)), "type")

// 多种存储服务的混合存储服务。需谨慎选择存储服务的组合，避免出Bug
type MashupStorageType struct {
	serder.Metadata `union:"Mashup"`
	Type            string      `json:"type"`
	Store           StorageType `json:"store"`   // 创建ShardStore或PublicStore时，使用的存储服务类型
	Feature         StorageType `json:"feature"` // 根据Feature创建组件时使用的存储服务类型
}

func (a *MashupStorageType) GetStorageType() string {
	return "Mashup"
}

func (a *MashupStorageType) String() string {
	return "Mashup"
}

type LocalStorageType struct {
	serder.Metadata `union:"Local"`
	Type            string `json:"type"`
}

func (a *LocalStorageType) GetStorageType() string {
	return "Local"
}

func (a *LocalStorageType) String() string {
	return "Local"
}

type OSSType struct {
	serder.Metadata `union:"OSS"`
	Type            string `json:"type"`
}

func (a *OSSType) GetStorageType() string {
	return "OSS"
}

func (a *OSSType) String() string {
	return "OSS"
}

type OBSType struct {
	serder.Metadata `union:"OBS"`
	Type            string `json:"type"`
}

func (a *OBSType) GetStorageType() string {
	return "OBS"
}

func (a *OBSType) String() string {
	return "OBS"
}

type COSType struct {
	serder.Metadata `union:"COS"`
	Type            string `json:"type"`
}

func (a *COSType) GetStorageType() string {
	return "COS"
}

func (a *COSType) String() string {
	return "COS"
}

type EFileType struct {
	serder.Metadata `union:"EFile"`
	Type            string `json:"type"`
}

func (a *EFileType) GetStorageType() string {
	return "EFile"
}

func (a *EFileType) String() string {
	return "EFile"
}

// 通用的S3协议的存储服务
type S3Type struct {
	serder.Metadata `union:"S3"`
	Type            string `json:"type"`
}

func (a *S3Type) GetStorageType() string {
	return "S3"
}

func (a *S3Type) String() string {
	return "S3"
}

type ShardStoreUserConfig struct {
	BaseDir string `json:"baseDir"`
	MaxSize int64  `json:"maxSize"`
}
