package resources

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

/*
* ComputeResource is a struct that represents a compute resource
* it defines the resource compute
 */
type ComputeResource struct {
	resource_model.AbstractResource
	Technology   TechnologyEnum `json:"technology" bson:"technology" default:"0"`             // Technology is the technology
	Architecture string         `json:"architecture,omitempty" bson:"architecture,omitempty"` // Architecture is the architecture
	Access       AccessEnum     `json:"access" bson:"access" default:"0"`                     // Access is the access

	Localisation string `json:"localisation,omitempty" bson:"localisation,omitempty"` // Localisation is the localisation

	CPUs []*CPU `bson:"cpus,omitempty" json:"cpus,omitempty"` // CPUs is the list of CPUs
	RAM  *RAM   `bson:"ram,omitempty" json:"ram,omitempty"`   // RAM is the RAM
	GPUs []*GPU `bson:"gpus,omitempty" json:"gpus,omitempty"` // GPUs is the list of GPUs
}

func (d *ComputeResource) GetAccessor(peerID string, groups []string, caller *tools.HTTPCaller) utils.Accessor {
	return New[*ComputeResource](tools.COMPUTE_RESOURCE, peerID, groups, caller, func() utils.DBObject { return &ComputeResource{} })
}

// CPU is a struct that represents a CPU
type CPU struct {
	Cores         uint   `bson:"cores,omitempty" json:"cores,omitempty"`               //TODO: validate
	Architecture  string `bson:"architecture,omitempty" json:"architecture,omitempty"` //TOOD: enum
	Shared        bool   `bson:"shared,omitempty" json:"shared,omitempty"`
	MinimumMemory uint   `bson:"minimum_memory,omitempty" json:"minimum_memory,omitempty"`
	Platform      string `bson:"platform,omitempty" json:"platform,omitempty"`
}

type RAM struct {
	Size uint `bson:"size,omitempty" json:"size,omitempty" description:"Units in MB"`
	Ecc  bool `bson:"ecc,omitempty" json:"ecc,omitempty"`
}

type GPU struct {
	CudaCores   uint   `bson:"cuda_cores,omitempty" json:"cuda_cores,omitempty"`
	Model       string `bson:"model,omitempty" json:"model,omitempty"`
	Memory      uint   `bson:"memory,omitempty" json:"memory,omitempty" description:"Units in MB"`
	TensorCores uint   `bson:"tensor_cores,omitempty" json:"tensor_cores,omitempty"`
}

type TechnologyEnum int

const (
	DOCKER TechnologyEnum = iota
	KUBERNETES
	SLURM
	HW
	CONDOR
)

func (t TechnologyEnum) String() string {
	return [...]string{"DOCKER", "KUBERNETES", "SLURM", "HW", "CONDOR"}[t]
}

type AccessEnum int

const (
	SSH AccessEnum = iota
	SSH_KUBE_API
	SSH_SLURM
	SSH_DOCKER
	OPENCLOUD
	VPN
)

func (a AccessEnum) String() string {
	return [...]string{"SSH", "SSH_KUBE_API", "SSH_SLURM", "SSH_DOCKER", "OPENCLOUD", "VPN"}[a]
}
