package models

import (
	"cloud.o-forge.io/core/oc-lib/logs"
	"cloud.o-forge.io/core/oc-lib/models/allowed_image"
	"cloud.o-forge.io/core/oc-lib/models/billing"
	"cloud.o-forge.io/core/oc-lib/models/billing/discount"
	"cloud.o-forge.io/core/oc-lib/models/billing/payment"
	"cloud.o-forge.io/core/oc-lib/models/billing/refund"
	"cloud.o-forge.io/core/oc-lib/models/billing/subscription"
	"cloud.o-forge.io/core/oc-lib/models/execution_verification"
	"cloud.o-forge.io/core/oc-lib/models/live"
	"cloud.o-forge.io/core/oc-lib/models/order"
	"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource"
	"cloud.o-forge.io/core/oc-lib/models/utils"
	"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"
	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 ModelsCatalog = 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.SERVICE_RESOURCE.String():       func() utils.DBObject { return &resource.ServiceResource{} },
	tools.NATIVE_TOOL.String():            func() utils.DBObject { return &resource.NativeTool{} },
	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.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{} },
	tools.ORDER.String():                  func() utils.DBObject { return &order.Order{} },
	tools.PURCHASE_RESOURCE.String():      func() utils.DBObject { return &purchase_resource.PurchaseResource{} },
	tools.LIVE_DATACENTER.String():        func() utils.DBObject { return &live.LiveDatacenter{} },
	tools.LIVE_STORAGE.String():           func() utils.DBObject { return &live.LiveStorage{} },
	tools.LIVE_SERVICE.String():           func() utils.DBObject { return &live.LiveService{} },
	tools.BILL.String():                   func() utils.DBObject { return &billing.Bill{} },
	tools.PAYMENT.String():                func() utils.DBObject { return &payment.Payment{} },
	tools.REFUND.String():                 func() utils.DBObject { return &refund.Refund{} },
	tools.DISCOUNT.String():               func() utils.DBObject { return &discount.Discount{} },
	tools.SUBSCRIPTION.String():           func() utils.DBObject { return &subscription.Subscription{} },
	tools.EXECUTION_VERIFICATION.String(): func() utils.DBObject { return &execution_verification.ExecutionVerification{} },
	tools.ALLOWED_IMAGE.String():          func() utils.DBObject { return &allowed_image.AllowedImage{} },
}

// Model returns the model object based on the model type
func Model(model int) utils.DBObject {
	log := logs.GetLogger()
	if model < 0 || model >= len(tools.Str) {
		log.Error().Msg("Can't find model: index out of range")
		return nil
	}
	key := tools.FromInt(model)
	if _, ok := ModelsCatalog[key]; ok {
		return ModelsCatalog[key]()
	}
	log.Error().Msg("Can't find model " + key + ".")
	return nil
}

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