package live

import (
	"slices"

	"cloud.o-forge.io/core/oc-lib/models/utils"
	"cloud.o-forge.io/core/oc-lib/tools"
	"github.com/biter777/countries"
)

/*
* LiveDatacenter is a struct that represents a compute units in your datacenters
 */
type Credentials struct {
	Login string `json:"login,omitempty" bson:"login,omitempty"`
	Pass  string `json:"password,omitempty" bson:"password,omitempty"`
	Token string `json:"token,omitempty" bson:"token,omitempty"`
}

type Certs struct {
	AuthorityCertificate string `json:"authority_certificate,omitempty" bson:"authority_certificate,omitempty"`
	ClientCertificate    string `json:"client_certificate,omitempty" bson:"client_certificate,omitempty"`
}

type LiveCerts struct {
	Host string `json:"host,omitempty" bson:"host,omitempty"`
	Port string `json:"port,omitempty" bson:"port,omitempty"`

	Certificates *Certs       `json:"certs,omitempty" bson:"certs,omitempty"`
	Credentials  *Credentials `json:"creds,omitempty" bson:"creds,omitempty"`
}

// TODO in the future multiple type of certs depending of infra type
type GeoPoint struct {
	Latitude  float64 `json:"latitude,omitempty" bson:"latitude,omitempty"`
	Longitude float64 `json:"longitude,omitempty" bson:"longitude,omitempty"`
}

type AbstractLive struct {
	utils.AbstractObject
	Certs LiveCerts `json:"certs,omitempty" bson:"certs,omitempty"`

	MonitorPath    string                `json:"monitor_path,omitempty" bson:"monitor_path,omitempty"`
	Location       GeoPoint              `json:"location,omitempty" bson:"location,omitempty"`
	Country        countries.CountryCode `json:"country,omitempty" bson:"country,omitempty"`
	AccessProtocol string                `json:"access_protocol,omitempty" bson:"access_protocol,omitempty"`
	ResourcesID    []string              `json:"resources_id" bson:"resources_id"`
}

func (ri *AbstractLive) Extend(typ ...string) map[string][]tools.DataType {
	ext := ri.AbstractObject.Extend(typ...)
	for _, t := range typ {
		switch t {
		case "resource":
			if _, ok := ext[t]; !ok {
				ext[t] = []tools.DataType{}
			}
			ext[t] = append(ext[t], tools.WORKFLOW_RESOURCE)
			ext[t] = append(ext[t], tools.DATA_RESOURCE)
			ext[t] = append(ext[t], tools.COMPUTE_RESOURCE)
			ext[t] = append(ext[t], tools.STORAGE_RESOURCE)
			ext[t] = append(ext[t], tools.PROCESSING_RESOURCE)
			ext[t] = append(ext[t], tools.SERVICE_RESOURCE)
		}
	}
	return ext
}

func (d *AbstractLive) GetMonitorPath() string {
	return d.MonitorPath
}

func (d *AbstractLive) GetResourcesID() []string {
	return d.ResourcesID
}

func (d *AbstractLive) SetResourcesID(resourcesid string) {
	if slices.Contains(d.ResourcesID, resourcesid) {
		d.ResourcesID = append(d.ResourcesID, resourcesid)
	}
}

func (r *AbstractLive) GetResourceType() tools.DataType {
	return tools.INVALID
}

func (r *AbstractLive) StoreDraftDefault() {
	r.IsDraft = false
}

func (r *AbstractLive) CanDelete() bool {
	return r.IsDraft // only draft ComputeUnits can be deleted
}
