package mq

import (
	"fmt"

	"gitlink.org.cn/cloudream/common/consts/errorcode"
	"gitlink.org.cn/cloudream/common/pkgs/logger"

	"gitlink.org.cn/cloudream/common/pkgs/mq"
	coormq "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/mq/coordinator"
	"gitlink.org.cn/cloudream/jcs-pub/coordinator/internal/db"
	cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types"
)

func (svc *Service) GetStorageDetails(msg *coormq.GetStorageDetails) (*coormq.GetStorageDetailsResp, *mq.CodeMessage) {
	d := svc.db
	stgs, err := db.DoTx02(d, func(tx db.SQLContext) ([]*cortypes.StorageDetail, error) {
		stgs, err := d.Storage().BatchGetByID(tx, msg.StorageIDs)
		if err != nil {
			return nil, fmt.Errorf("getting storages: %v", err)
		}
		stgMap := make(map[cortypes.StorageID]*cortypes.Storage)
		for _, stg := range stgs {
			s := stg
			stgMap[stg.StorageID] = &s
		}

		hubIDs := make([]cortypes.HubID, 0, len(stgs))
		for _, stg := range stgs {
			if stg.MasterHub != 0 {
				hubIDs = append(hubIDs, stg.MasterHub)
			}
		}

		hubs, err := d.Hub().BatchGetByID(tx, hubIDs)
		if err != nil {
			return nil, fmt.Errorf("getting hubs: %v", err)
		}

		hubMap := make(map[cortypes.HubID]*cortypes.Hub)
		for _, hub := range hubs {
			h := hub
			hubMap[hub.HubID] = &h
		}

		details := make([]*cortypes.StorageDetail, len(msg.StorageIDs))
		for i, stgID := range msg.StorageIDs {
			stg := stgMap[stgID]
			if stg == nil {
				continue
			}
			details[i] = &cortypes.StorageDetail{
				Storage:   *stg,
				MasterHub: hubMap[stg.MasterHub],
			}
		}

		return details, nil
	})
	if err != nil {
		logger.Warnf("getting storage details: %s", err.Error())
		return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("getting storage details: %v", err))
	}

	return mq.ReplyOK(coormq.RespGetStorageDetails(stgs))
}
