# We use constraints to set AntiAffinity in K8s
# https://discourse.charmhub.io/t/pod-priority-and-affinity-in-juju-charms/4091/13?u=jose

# FIXME: Passing an empty constraints value to the Juju Terraform provider currently
# causes the operation to fail due to https://github.com/juju/terraform-provider-juju/issues/344
# Therefore, we set a default value of "arch=amd64" for all applications.

variable "risk" {
  description = "Risk level that the applications are (unless overwritten by individual channels) deployed from"
  type        = string
  default     = "stable"
}

variable "model" {
  description = "Model configuration. When `uuid` is set, an existing model is looked up; otherwise a new model is created with the given fields. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/model"
  type = object({
    uuid = optional(string)
    name = optional(string, "cos")
    cloud = optional(object({
      name   = string
      region = optional(string)
    }))
    annotations       = optional(map(string))
    config            = optional(map(string))
    constraints       = optional(string)
    credential        = optional(string)
    target_controller = optional(string)
  })
  default = {}

  validation {
    condition = var.model.uuid == null || (
      var.model.annotations == null &&
      var.model.cloud == null &&
      var.model.config == null &&
      var.model.constraints == null &&
      var.model.credential == null &&
      var.model.target_controller == null
    )
    error_message = "When `model.uuid` is set, the model already exists; do not also set `annotations`, `cloud`, `config`, `constraints`, `credential`, or `target_controller`."
  }

  validation {
    condition     = var.model.uuid != null || (var.model.name != null && length(var.model.name) > 0)
    error_message = "`model.name` must be non-empty when creating a model (i.e. when `model.uuid` is null)."
  }

  validation {
    condition     = var.model.uuid == null || can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", var.model.uuid))
    error_message = "`model.uuid` must be a valid UUID."
  }
}

variable "cloud" {
  description = "Kubernetes cloud or environment where this COS module will be deployed (e.g self-managed, aws)"
  type        = string
  default     = "self-managed"
  validation {
    condition     = contains(["aws", "self-managed"], var.cloud)
    error_message = "Allowed values are: aws, self-managed."
  }
}

variable "anti_affinity" {
  description = "Enable anti-affinity constraints across all HA modules (Mimir, Loki, Tempo)"
  type        = bool
  default     = true
}

# -------------- # Network configurations --------------

variable "internal_tls" {
  description = "Specify whether to use TLS or not for internal COS communication. By default, TLS is enabled using self-signed-certificates"
  type        = bool
  default     = true
}

variable "external_certificates_offer_url" {
  description = "A Juju offer URL of a CA providing the 'tls_certificates' integration for Traefik to supply it with server certificates"
  type        = string
  default     = null

  validation {
    condition = (
      (var.external_certificates_offer_url == null && var.external_ca_cert_offer_url == null) ||
      (var.external_certificates_offer_url != null && var.external_ca_cert_offer_url != null)
    )
    error_message = "external_certificates_offer_url and external_ca_cert_offer_url must be supplied together (either both set or both null)."
  }
}

variable "external_ca_cert_offer_url" {
  description = "A Juju offer URL (e.g. admin/external-ca.send-ca-cert) of a CA providing the 'certificate_transfer' integration for applications to trust ingress via Traefik."
  type        = string
  default     = null
}

variable "postgresql_offer_url" {
  description = "A Juju offer URL (e.g. admin/postgresql.database) of a PostgreSQL service providing the 'postgresql_client' integration for applications to connect to the database."
  type        = string
  default     = null

  validation {
    condition     = !(var.postgresql_offer_url == null && var.grafana.units > 1)
    error_message = "postgresql_offer_url must be supplied when Grafana is scaled > 1 due to its database requirements."
  }
}

# -------------- # Ingress configurations --------------

variable "ingress" {
  description = "Per-component toggle for ingress integrations"
  type = object({
    alertmanager            = optional(bool, true)
    catalogue               = optional(bool, true)
    grafana                 = optional(bool, true)
    loki                    = optional(bool, true)
    mimir                   = optional(bool, true)
    opentelemetry_collector = optional(bool, true)
    tempo                   = optional(bool, false)
  })
  default = {}

  validation {
    condition     = !(var.ingress.opentelemetry_collector == true && var.ingress.tempo == true)
    error_message = "opentelemetry_collector and tempo cannot both be enabled. See https://github.com/canonical/observability-stack/issues/382"
  }
}

# -------------- # S3 storage configuration --------------

variable "s3_endpoint" {
  description = "S3 endpoint"
  type        = string
}

variable "s3_access_key" {
  description = "S3 access-key credential"
  type        = string
  sensitive   = true
}

variable "s3_secret_key" {
  description = "S3 secret-key credential"
  type        = string
  sensitive   = true
}

variable "loki_bucket" {
  description = "Loki bucket name"
  type        = string
  sensitive   = true
  default     = "loki"
}

variable "mimir_bucket" {
  description = "Mimir bucket name"
  type        = string
  sensitive   = true
  default     = "mimir"
}

variable "tempo_bucket" {
  description = "Tempo bucket name"
  type        = string
  sensitive   = true
  default     = "tempo"
}

# -------------- # Application configurations --------------

variable "alertmanager" {
  type = object({
    app_name           = optional(string, "alertmanager")
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for Alertmanager. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "catalogue" {
  type = object({
    app_name           = optional(string, "catalogue")
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 1)
  })
  default     = {}
  description = "Application configuration for Catalogue. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "grafana" {
  type = object({
    app_name           = optional(string, "grafana")
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for Grafana. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "loki_coordinator" {
  type = object({
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for Loki Coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "loki_worker" {
  type = object({
    backend_config             = optional(map(string), {})
    read_config                = optional(map(string), {})
    write_config               = optional(map(string), {})
    constraints                = optional(string, "arch=amd64")
    resources                  = optional(map(string), {})
    revision                   = optional(number, null)
    backend_storage_directives = optional(map(string), {})
    read_storage_directives    = optional(map(string), {})
    write_storage_directives   = optional(map(string), {})
    backend_units              = optional(number, 3)
    read_units                 = optional(number, 3)
    write_units                = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for all Loki Workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "mimir_coordinator" {
  type = object({
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    revision           = optional(number, null)
    resources          = optional(map(string), {})
    storage_directives = optional(map(string), {})
    units              = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for Mimir Coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "mimir_worker" {
  type = object({
    backend_config             = optional(map(string), {})
    read_config                = optional(map(string), {})
    write_config               = optional(map(string), {})
    constraints                = optional(string, "arch=amd64")
    resources                  = optional(map(string), {})
    revision                   = optional(number, null)
    backend_storage_directives = optional(map(string), {})
    read_storage_directives    = optional(map(string), {})
    write_storage_directives   = optional(map(string), {})
    backend_units              = optional(number, 3)
    read_units                 = optional(number, 3)
    write_units                = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for all Mimir Workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "opentelemetry_collector" {
  type = object({
    app_name           = optional(string, "otelcol")
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 1)
  })
  default     = {}
  description = "Application configuration for OpenTelemetry Collector. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "ssc" {
  type = object({
    app_name           = optional(string, "ca")
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 1)
  })
  default     = {}
  description = "Application configuration for Self-signed-certificates. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "s3_integrator" {
  type = object({
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 1)
  })
  default     = {}
  description = "Application configuration for all S3-integrators in coordinated workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "tempo_coordinator" {
  type = object({
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for Tempo Coordinator. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "tempo_worker" {
  type = object({
    querier_config                              = optional(map(string), {})
    query_frontend_config                       = optional(map(string), {})
    ingester_config                             = optional(map(string), {})
    distributor_config                          = optional(map(string), {})
    compactor_config                            = optional(map(string), {})
    metrics_generator_config                    = optional(map(string), {})
    constraints                                 = optional(string, "arch=amd64")
    resources                                   = optional(map(string), {})
    revision                                    = optional(number, null)
    compactor_worker_storage_directives         = optional(map(string), {})
    distributor_worker_storage_directives       = optional(map(string), {})
    ingester_worker_storage_directives          = optional(map(string), {})
    metrics_generator_worker_storage_directives = optional(map(string), {})
    querier_worker_storage_directives           = optional(map(string), {})
    query_frontend_worker_storage_directives    = optional(map(string), {})
    compactor_units                             = optional(number, 3)
    distributor_units                           = optional(number, 3)
    ingester_units                              = optional(number, 3)
    metrics_generator_units                     = optional(number, 3)
    querier_units                               = optional(number, 3)
    query_frontend_units                        = optional(number, 3)
  })
  default     = {}
  description = "Application configuration for all Tempo workers. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}

variable "traefik" {
  type = object({
    app_name           = optional(string, "traefik")
    config             = optional(map(string), {})
    constraints        = optional(string, "arch=amd64")
    resources          = optional(map(string), {})
    revision           = optional(number, null)
    storage_directives = optional(map(string), {})
    units              = optional(number, 1)
  })
  default     = {}
  description = "Application configuration for Traefik. For more details: https://registry.terraform.io/providers/juju/juju/latest/docs/resources/application"
}
