package resources

import (
	"cloud.o-forge.io/core/oc-lib/models/utils"
	"cloud.o-forge.io/core/oc-lib/tools"
)

type ResourceSet struct {
	Datas       []string `bson:"datas,omitempty" json:"datas,omitempty"`
	Storages    []string `bson:"storages,omitempty" json:"storages,omitempty"`
	Processings []string `bson:"processings,omitempty" json:"processings,omitempty"`
	Computes    []string `bson:"computes,omitempty" json:"computes,omitempty"`
	Workflows   []string `bson:"workflows,omitempty" json:"workflows,omitempty"`
	NativeTool  []string `bson:"native,omitempty" json:"native,omitempty"`
	Services    []string `bson:"services,omitempty" json:"services,omitempty"`
	Dynamics    []string `bson:"dynamics,omitempty" json:"dynamics,omitempty"`

	// DynamicResources are stored inline — no DB collection, resolved at runtime via SetAllowedInstances.
	DynamicResources    []*DynamicResource    `bson:"-" json:"dynamic_resources,omitempty"`
	DataResources       []*DataResource       `bson:"-" json:"data_resources,omitempty"`
	StorageResources    []*StorageResource    `bson:"-" json:"storage_resources,omitempty"`
	ProcessingResources []*ProcessingResource `bson:"-" json:"processing_resources,omitempty"`
	ComputeResources    []*ComputeResource    `bson:"-" json:"compute_resources,omitempty"`
	WorkflowResources   []*WorkflowResource   `bson:"-" json:"workflow_resources,omitempty"`
	NativeTools         []*NativeTool         `bson:"-" json:"native_tools,omitempty"`
	ServiceResources    []*ServiceResource    `bson:"-" json:"service_resources,omitempty"`
}

func (r *ResourceSet) Clear() {
	r.DataResources = nil
	r.StorageResources = nil
	r.ProcessingResources = nil
	r.ComputeResources = nil
	r.WorkflowResources = nil
	r.ServiceResources = nil
	r.DynamicResources = nil
}

func (r *ResourceSet) Fill(request *tools.APIRequest) {
	r.Clear()
	for k, v := range map[utils.DBObject][]string{
		(&DataResource{}):       r.Datas,
		(&ComputeResource{}):    r.Computes,
		(&StorageResource{}):    r.Storages,
		(&ProcessingResource{}): r.Processings,
		(&WorkflowResource{}):   r.Workflows,
		(&ServiceResource{}):    r.Services,
		(&DynamicResource{}):    r.Dynamics,
	} {
		for _, id := range v {
			d, _, e := k.GetAccessor(request).LoadOne(id)
			if e == nil {
				switch k.(type) {
				case *DataResource:
					r.DataResources = append(r.DataResources, d.(*DataResource))
				case *ComputeResource:
					r.ComputeResources = append(r.ComputeResources, d.(*ComputeResource))
				case *StorageResource:
					r.StorageResources = append(r.StorageResources, d.(*StorageResource))
				case *ProcessingResource:
					r.ProcessingResources = append(r.ProcessingResources, d.(*ProcessingResource))
				case *WorkflowResource:
					r.WorkflowResources = append(r.WorkflowResources, d.(*WorkflowResource))
				case *ServiceResource:
					r.ServiceResources = append(r.ServiceResources, d.(*ServiceResource))
				case *DynamicResource:
					r.DynamicResources = append(r.DynamicResources, d.(*DynamicResource))
				}
			}
		}
	}
	for _, d := range r.DynamicResources {
		d.SetAllowedInstances(request)
	}
}

type ItemResource struct {
	Data       *DataResource       `bson:"data,omitempty" json:"data,omitempty"`
	Processing *ProcessingResource `bson:"processing,omitempty" json:"processing,omitempty"`
	Storage    *StorageResource    `bson:"storage,omitempty" json:"storage,omitempty"`
	Compute    *ComputeResource    `bson:"compute,omitempty" json:"compute,omitempty"`
	Workflow   *WorkflowResource   `bson:"workflow,omitempty" json:"workflow,omitempty"`
	NativeTool *NativeTool         `bson:"native_tools,omitempty" json:"native_tools,omitempty"`
	Service    *ServiceResource    `bson:"service,omitempty" json:"service,omitempty"`
	Dynamic    *DynamicResource    `bson:"dynamic,omitempty" json:"dynamic,omitempty"`
}
