package plans

import (
	"gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec"
	"gitlink.org.cn/cloudream/common/pkgs/ioswitch/plan"
	clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
	"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/ops2"
	"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
)

func CompleteMultipart(blocks []clitypes.ObjectBlock, blockSpaces []clitypes.UserSpaceDetail, targetSpace clitypes.UserSpaceDetail, shardInfoKey string, blder *exec.PlanBuilder) error {
	da := ops2.NewGraphNodeBuilder()

	sizes := make([]int64, len(blocks))
	for i, blk := range blocks {
		sizes[i] = blk.Size
	}
	joinNode := da.NewSegmentJoin(sizes)
	joinNode.Env().ToEnvWorker(getWorkerInfo(*targetSpace.MasterHub))
	joinNode.Env().Pinned = true

	for i, blk := range blocks {
		rd := da.NewShardRead(nil, blockSpaces[i], types.NewOpen(blk.FileHash))
		rd.Env().ToEnvWorker(getWorkerInfo(*blockSpaces[i].MasterHub))
		rd.Env().Pinned = true

		rd.Output().ToSlot(joinNode.InputSlot(i))
	}

	// TODO 应该采取更合理的方式同时支持Parser和直接生成DAG
	wr := da.NewShardWrite(nil, targetSpace, shardInfoKey)
	wr.Env().ToEnvWorker(getWorkerInfo(*targetSpace.MasterHub))
	wr.Env().Pinned = true

	joinNode.Joined().ToSlot(wr.Input())

	if shardInfoKey != "" {
		store := da.NewStore()
		store.Env().ToEnvDriver()
		store.Store(shardInfoKey, wr.FileHashVar())
	}

	err := plan.Compile(da.Graph, blder)
	if err != nil {
		return err
	}

	return nil
}
