package models

import (
	"cloud.o-forge.io/core/oc-lib/logs"
	"cloud.o-forge.io/core/oc-lib/tools"

	"cloud.o-forge.io/core/oc-lib/models/booking"
	"cloud.o-forge.io/core/oc-lib/models/collaborative_area"
	"cloud.o-forge.io/core/oc-lib/models/collaborative_area/rules/rule"
	"cloud.o-forge.io/core/oc-lib/models/peer"
	resource "cloud.o-forge.io/core/oc-lib/models/resources"
	"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
	"cloud.o-forge.io/core/oc-lib/models/utils"
	w2 "cloud.o-forge.io/core/oc-lib/models/workflow"
	"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
	w3 "cloud.o-forge.io/core/oc-lib/models/workspace"
)

/*
This package contains the models used in the application
It's used to create the models dynamically
*/
var models = map[string]func() utils.DBObject{
	tools.WORKFLOW_RESOURCE.String():   func() utils.DBObject { return &resource.WorkflowResource{} },
	tools.DATA_RESOURCE.String():       func() utils.DBObject { return &resource.DataResource{} },
	tools.COMPUTE_RESOURCE.String():    func() utils.DBObject { return &resource.ComputeResource{} },
	tools.STORAGE_RESOURCE.String():    func() utils.DBObject { return &resource.StorageResource{} },
	tools.PROCESSING_RESOURCE.String(): func() utils.DBObject { return &resource.ProcessingResource{} },
	tools.WORKFLOW.String():            func() utils.DBObject { return &w2.Workflow{} },
	tools.WORKFLOW_EXECUTION.String():  func() utils.DBObject { return &workflow_execution.WorkflowExecution{} },
	tools.WORKSPACE.String():           func() utils.DBObject { return &w3.Workspace{} },
	tools.RESOURCE_MODEL.String():      func() utils.DBObject { return &resource_model.ResourceModel{} },
	tools.PEER.String():                func() utils.DBObject { return &peer.Peer{} },
	tools.COLLABORATIVE_AREA.String():  func() utils.DBObject { return &collaborative_area.CollaborativeArea{} },
	tools.RULE.String():                func() utils.DBObject { return &rule.Rule{} },
	tools.BOOKING.String():             func() utils.DBObject { return &booking.Booking{} },
	tools.WORKFLOW_HISTORY.String():    func() utils.DBObject { return &w2.WorkflowHistory{} },
	tools.WORKSPACE_HISTORY.String():   func() utils.DBObject { return &w3.WorkspaceHistory{} },
}

// Model returns the model object based on the model type
func Model(model int) utils.DBObject {
	log := logs.GetLogger()
	if _, ok := models[tools.FromInt(model)]; ok {
		return models[tools.FromInt(model)]()
	}
	log.Error().Msg("Can't find model " + tools.FromInt(model) + ".")
	return nil
}

// GetModelsNames returns the names of the models
func GetModelsNames() []string {
	names := []string{}
	for name := range models {
		names = append(names, name)
	}
	return names
}
