package local

import (
	"fmt"

	clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
	"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory/reg"
	"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
	"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/utils"
	cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types"
)

func init() {
	reg.RegisterBuilder[*cortypes.LocalStorageType](func(detail *clitypes.UserSpaceDetail) types.StorageBuilder {
		return &builder{
			detail: detail,
		}
	})
}

type builder struct {
	types.EmptyBuilder
	detail *clitypes.UserSpaceDetail
}

func (b *builder) FeatureDesc() types.FeatureDesc {
	return types.FeatureDesc{
		HasBypassShardWrite: true,
		HasBypassShardRead:  true,
	}
}

func (b *builder) CreateShardStore() (types.ShardStore, error) {
	cred, ok := b.detail.UserSpace.Credential.(*cortypes.LocalCred)
	if !ok {
		return nil, fmt.Errorf("invalid storage credential type %T for local storage", b.detail.UserSpace.Credential)
	}

	return NewShardStore(cred.RootDir, b.detail)
}

func (b *builder) CreatePublicStore() (types.PublicStore, error) {
	cred, ok := b.detail.UserSpace.Credential.(*cortypes.LocalCred)
	if !ok {
		return nil, fmt.Errorf("invalid storage credential type %T for local storage", b.detail.UserSpace.Credential)
	}

	return NewPublicStore(cred.RootDir, b.detail)
}

func (b *builder) CreateMultiparter() (types.Multiparter, error) {
	feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail.Storage)
	if feat == nil {
		return nil, fmt.Errorf("feature %T not found", cortypes.MultipartUploadFeature{})
	}

	return &Multiparter{
		feat: feat,
	}, nil
}

func (b *builder) CreateS2STransfer() (types.S2STransfer, error) {
	feat := utils.FindFeature[*cortypes.S2STransferFeature](b.detail.Storage)
	if feat == nil {
		return nil, fmt.Errorf("feature %T not found", cortypes.S2STransferFeature{})
	}

	return &S2STransfer{
		detail: b.detail,
	}, nil
}
