package http

/*
import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/samber/lo"
	"gitlink.org.cn/cloudream/common/consts/errorcode"
	"gitlink.org.cn/cloudream/common/pkgs/logger"
	"gitlink.org.cn/cloudream/jcs-pub/client/types"
)

type TempService struct {
	*Server
}

func (s *Server) Temp() *TempService {
	return &TempService{
		Server: s,
	}
}

type TempListDetailsResp struct {
	Buckets []BucketDetail `json:"buckets"`
}
type BucketDetail struct {
	BucketID    types.BucketID `json:"bucketID"`
	Name        string         `json:"name"`
	ObjectCount int            `json:"objectCount"`
}

func (s *TempService) ListDetails(ctx *gin.Context) {
	log := logger.WithField("HTTP", "Bucket.ListBucketsDetails")

	bkts, err := s.svc.BucketSvc().GetUserBuckets(1)
	if err != nil {
		log.Warnf("getting user buckets: %s", err.Error())
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get user buckets failed"))
		return
	}

	details := make([]BucketDetail, len(bkts))
	for i := range bkts {
		details[i].BucketID = bkts[i].BucketID
		details[i].Name = bkts[i].Name
		objs, err := s.getBucketObjects(bkts[i].BucketID)
		if err != nil {
			log.Warnf("getting bucket objects: %s", err.Error())
			ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get bucket objects failed"))
			return
		}
		details[i].ObjectCount = len(objs)
	}

	ctx.JSON(http.StatusOK, OK(TempListDetailsResp{
		Buckets: details,
	}))
}

type TempGetObjects struct {
	BucketID types.BucketID `form:"bucketID"`
}
type BucketGetObjectsResp struct {
	Objects []types.Object `json:"objects"`
}

func (s *TempService) GetObjects(ctx *gin.Context) {
	log := logger.WithField("HTTP", "Bucket.ListBucketsDetails")

	var req TempGetObjects
	if err := ctx.ShouldBindQuery(&req); err != nil {
		log.Warnf("binding query: %s", err.Error())
		ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
		return
	}

	objs, err := s.getBucketObjects(req.BucketID)
	if err != nil {
		log.Warnf("getting bucket objects: %s", err.Error())
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get bucket objects failed"))
		return
	}

	ctx.JSON(http.StatusOK, OK(BucketGetObjectsResp{
		Objects: objs,
	}))
}

type TempGetObjectDetail struct {
	ObjectID types.ObjectID `form:"objectID"`
}
type TempGetObjectDetailResp struct {
	Blocks []ObjectBlockDetail `json:"blocks"`
}
type ObjectBlockDetail struct {
	ObjectID     types.ObjectID `json:"objectID"`
	Type         string         `json:"type"`
	FileHash     types.FileHash `json:"fileHash"`
	LocationType string         `json:"locationType"`
	LocationName string         `json:"locationName"`
}

func (s *TempService) GetObjectDetail(ctx *gin.Context) {
	log := logger.WithField("HTTP", "Object.GetObjectDetail")

	var req TempGetObjectDetail
	if err := ctx.ShouldBindQuery(&req); err != nil {
		log.Warnf("binding query: %s", err.Error())
		ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument"))
		return
	}

	details, err := s.svc.ObjectSvc().GetObjectDetail(req.ObjectID)
	if err != nil {
		log.Warnf("getting object detail: %s", err.Error())
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get object detail failed"))
		return
	}
	if details == nil {
		log.Warnf("object not found")
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "object not found"))
		return
	}

	var allSpaceIDs []types.UserSpaceID
	allSpaceIDs = append(allSpaceIDs, details.PinnedAt...)
	for _, b := range details.Blocks {
		allSpaceIDs = append(allSpaceIDs, b.UserSpaceID)
	}

	allSpaceIDs = lo.Uniq(allSpaceIDs)

	getStgs, err := s.svc.StorageSvc().GetDetails(allSpaceIDs)
	if err != nil {
		log.Warnf("getting nodes: %s", err.Error())
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get nodes failed"))
		return
	}

	allStgs := make(map[types.UserSpaceID]types.UserSpace)
	for _, n := range getStgs {
		if n != nil {
			allStgs[n.Storage.UserSpaceID] = n.UserSpace
		}
	}

	var blocks []ObjectBlockDetail

	for _, spaceID := range details.PinnedAt {
		blocks = append(blocks, ObjectBlockDetail{
			Type:         "Rep",
			FileHash:     details.Object.FileHash,
			LocationType: "Agent",
			LocationName: allStgs[spaceID].Name,
		})
	}

	switch details.Object.Redundancy.(type) {
	case *types.NoneRedundancy:
		for _, blk := range details.Blocks {
			if !lo.Contains(details.PinnedAt, blk.UserSpaceID) {
				blocks = append(blocks, ObjectBlockDetail{
					Type:         "Rep",
					FileHash:     blk.FileHash,
					LocationType: "Agent",
					LocationName: allStgs[blk.UserSpaceID].Name,
				})
			}
		}
	case *types.RepRedundancy:
		for _, blk := range details.Blocks {
			if !lo.Contains(details.PinnedAt, blk.UserSpaceID) {
				blocks = append(blocks, ObjectBlockDetail{
					Type:         "Rep",
					FileHash:     blk.FileHash,
					LocationType: "Agent",
					LocationName: allStgs[blk.UserSpaceID].Name,
				})
			}
		}

	case *types.ECRedundancy:
		for _, blk := range details.Blocks {
			blocks = append(blocks, ObjectBlockDetail{
				Type:         "Block",
				FileHash:     blk.FileHash,
				LocationType: "Agent",
				LocationName: allStgs[blk.UserSpaceID].Name,
			})
		}
	}

	ctx.JSON(http.StatusOK, OK(TempGetObjectDetailResp{
		Blocks: blocks,
	}))
}

func (s *TempService) getBucketObjects(bktID types.BucketID) ([]types.Object, error) {
	pkgs, err := s.svc.PackageSvc().GetBucketPackages(1, bktID)
	if err != nil {
		return nil, err
	}

	var allObjs []types.Object
	for _, pkg := range pkgs {
		objs, err := s.svc.ObjectSvc().GetPackageObjects(1, pkg.PackageID)
		if err != nil {
			return nil, err
		}
		allObjs = append(allObjs, objs...)
	}

	return allObjs, nil
}

type TempGetDatabaseAll struct {
}
type TempGetDatabaseAllResp struct {
	Buckets []BucketDetail      `json:"buckets"`
	Objects []BucketObject      `json:"objects"`
	Blocks  []ObjectBlockDetail `json:"blocks"`
}
type BucketObject struct {
	types.Object
	BucketID types.BucketID `json:"bucketID"`
}

func (s *TempService) GetDatabaseAll(ctx *gin.Context) {
	log := logger.WithField("HTTP", "Temp.GetDatabaseAll")

	db, err := s.svc.ObjectSvc().GetDatabaseAll()
	if err != nil {
		log.Warnf("getting database all: %s", err.Error())
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get database all failed"))
		return
	}

	var allSpaceIDs []types.UserSpaceID
	for _, obj := range db.Objects {
		allSpaceIDs = append(allSpaceIDs, obj.PinnedAt...)
		for _, blk := range obj.Blocks {
			allSpaceIDs = append(allSpaceIDs, blk.UserSpaceID)
		}
	}

	getStgs, err := s.svc.StorageSvc().GetDetails(allSpaceIDs)
	if err != nil {
		log.Warnf("getting nodes: %s", err.Error())
		ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get nodes failed"))
		return
	}
	allStgs := make(map[types.UserSpaceID]types.Storage)
	for _, n := range getStgs {
		if n != nil {
			allStgs[n.Storage.UserSpaceID] = n.Storage
		}
	}

	bkts := make(map[types.BucketID]*BucketDetail)
	for _, bkt := range db.Buckets {
		bkts[bkt.BucketID] = &BucketDetail{
			BucketID:    bkt.BucketID,
			Name:        bkt.Name,
			ObjectCount: 0,
		}
	}

	type PackageDetail struct {
		Package types.Package
		// Loaded  []types.Node
	}
	pkgs := make(map[types.PackageID]*PackageDetail)
	for _, pkg := range db.Packages {
		p := PackageDetail{
			Package: pkg,
			// Loaded:  make([]types.Node, 0),
		}

		// loaded, err := s.svc.PackageSvc().GetLoadedNodes(1, pkg.PackageID)
		// if err != nil {
		// 	log.Warnf("getting loaded nodes: %s", err.Error())
		// 	ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get loaded nodes failed"))
		// 	return
		// }

		// for _, hubID := range loaded {
		// 	p.Loaded = append(p.Loaded, allNodes[hubID])
		// }

		pkgs[pkg.PackageID] = &p
	}

	var objs []BucketObject
	for _, obj := range db.Objects {
		o := BucketObject{
			Object:   obj.Object,
			BucketID: pkgs[obj.Object.PackageID].Package.BucketID,
		}
		objs = append(objs, o)
	}

	var blocks []ObjectBlockDetail
	for _, obj := range db.Objects {
		bkts[pkgs[obj.Object.PackageID].Package.BucketID].ObjectCount++

		for _, hubID := range obj.PinnedAt {
			blocks = append(blocks, ObjectBlockDetail{
				ObjectID:     obj.Object.ObjectID,
				Type:         "Rep",
				FileHash:     obj.Object.FileHash,
				LocationType: "Agent",
				LocationName: allStgs[hubID].Name,
			})
		}

		switch obj.Object.Redundancy.(type) {
		case *types.NoneRedundancy:
			for _, blk := range obj.Blocks {
				if !lo.Contains(obj.PinnedAt, blk.UserSpaceID) {
					blocks = append(blocks, ObjectBlockDetail{
						ObjectID:     obj.Object.ObjectID,
						Type:         "Rep",
						FileHash:     blk.FileHash,
						LocationType: "Agent",
						LocationName: allStgs[blk.UserSpaceID].Name,
					})
				}
			}
		case *types.RepRedundancy:
			for _, blk := range obj.Blocks {
				if !lo.Contains(obj.PinnedAt, blk.UserSpaceID) {
					blocks = append(blocks, ObjectBlockDetail{
						ObjectID:     obj.Object.ObjectID,
						Type:         "Rep",
						FileHash:     blk.FileHash,
						LocationType: "Agent",
						LocationName: allStgs[blk.UserSpaceID].Name,
					})
				}
			}

		case *types.ECRedundancy:
			for _, blk := range obj.Blocks {
				blocks = append(blocks, ObjectBlockDetail{
					ObjectID:     obj.Object.ObjectID,
					Type:         "Block",
					FileHash:     blk.FileHash,
					LocationType: "Agent",
					LocationName: allStgs[blk.UserSpaceID].Name,
				})
			}
		}

		// for _, node := range pkgs[obj.Object.PackageID].Loaded {
		// 	blocks = append(blocks, ObjectBlockDetail{
		// 		ObjectID:     obj.Object.ObjectID,
		// 		Type:         "Rep",
		// 		FileHash:     obj.Object.FileHash,
		// 		LocationType: "Storage",
		// 		LocationName: allNodes[node.HubID].Name,
		// 	})
		// }

	}

	ctx.JSON(http.StatusOK, OK(TempGetDatabaseAllResp{
		Buckets: lo.Map(lo.Values(bkts), func(b *BucketDetail, _ int) BucketDetail { return *b }),
		Objects: objs,
		Blocks:  blocks,
	}))
}

func initTemp(rt gin.IRoutes, s *Server) {
	rt.GET("/bucket/listDetails", s.Temp().ListDetails)
	rt.GET("/bucket/getObjects", s.Temp().GetObjects)
	rt.GET("/object/getDetail", s.Temp().GetObjectDetail)
	rt.GET("/temp/getDatabaseAll", s.Temp().GetDatabaseAll)
}

func auth(ctx *gin.Context) {
	token := ctx.Request.Header.Get("X-CDS-Auth")
	if token != "cloudream@123" {
		ctx.AbortWithStatus(http.StatusUnauthorized)
	}
}
*/
