# External services — message brokers, LLM backends, object storage, …
#
# All sensitive values use '${ENV_VAR}' tokens resolved after deserialisation.
# Set real values in .env — never inline credentials here.
# Required env vars (add to .env as needed):
#   NATS_URL, NATS_TOKEN
#   NATS_ADMIN_URL, NATS_ADMIN_CREDENTIALS_FILE, NATS_ADMIN_NAMESPACE_PREFIX, NATS_ADMIN_NAMESPACE_ENV
#   OLLAMA_BASE_URL
#   S3_ENDPOINT, S3_REGION, S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY
#
# To activate a service: set enabled = true and configure the matching env vars.

let C = import "external-services/contracts.ncl" in

{
  external_services = {

    # ── NATS — message broker / event bus ─────────────────────────────────────
    nats = {
      enabled            = true,
      url                = "${NATS_URL}",
      token              = "${NATS_TOKEN}",
      connection_timeout = 5,
      max_reconnects     = 10,
      reconnect_delay    = 2,
      subjects = {
        events  = "app.events",
        notify  = "app.notifications",
        control = "app.control",
      },
    } | C.NatsConfig,

    # ── NATS Admin — operational bus for supervisor toolkit ───────────────────
    # Separate connection from the general app NATS: different credentials,
    # namespace-scoped subjects, and JetStream for audit log.
    #
    # Leaf-node topology: the web server connects outbound to the hub —
    # no inbound ports required in k8s.
    #
    # Subject full path assembled at runtime:
    #   {namespace.prefix}.{namespace.env}.{subjects.*}
    #   e.g. "evol.website.prod.admin.logs"
    #
    # To override namespace.env per Deployment without changing this file:
    #   set NATS_ADMIN_NAMESPACE_ENV=staging in the k8s Deployment env.
    nats_admin = {
      enabled            = true,
      url                = "${NATS_ADMIN_URL}",
      credentials_file   = "${NATS_ADMIN_CREDENTIALS_FILE}",
      connection_timeout = 5,
      max_reconnects     = 10,
      reconnect_delay    = 2,

      namespace = {
        prefix = "${NATS_ADMIN_NAMESPACE_PREFIX}",
        env    = "${NATS_ADMIN_NAMESPACE_ENV}",
      },

      subjects = {
        # Admin operational subjects (leaf — prefix+env prepended at runtime)
        logs    = "admin.logs",
        health  = "admin.health",
        users   = "admin.users",
        # Ops signals from CI/CD pipeline
        deploy  = "ops.deploy",
        reload  = "ops.config-reload",
      },

      jetstream = {
        enabled        = true,
        stream_name    = "rustelo-admin",
        retention_days = 30,
        retention      = "Limits",
        storage        = "File",
        max_messages   = 0,
        max_bytes      = 0,
        consumers = [
          {
            name            = "rustelo-pipelines",
            ack_policy      = "Explicit",
            filter_subjects = [],
          },
        ],
      },

      nkey_seed                = "${NATS_ADMIN_NKEY_SEED}",
      require_signed_messages  = false,
      trusted_nkeys            = [],
    } | C.NatsAdminConfig,

    # ── Ollama — local LLM inference ──────────────────────────────────────────
    ollama = {
      enabled         = false,
      base_url        = "${OLLAMA_BASE_URL}",
      default_model   = "llama3",
      request_timeout = 120,
      stream          = true,
      keep_alive      = "5m",
      max_tokens      = 2048,
      temperature     = 0.7,
    } | C.OllamaConfig,

    # ── S3-compatible object storage (AWS S3, MinIO, R2, …) ──────────────────
    s3 = {
      enabled         = false,
      endpoint        = "${S3_ENDPOINT}",
      region          = "${S3_REGION}",
      bucket          = "${S3_BUCKET}",
      access_key      = "${S3_ACCESS_KEY}",
      secret_key      = "${S3_SECRET_KEY}",
      path_style      = false,
      upload_prefix   = "uploads/",
      max_object_size = 104857600,
      presign_ttl     = 3600,
    } | C.S3Config,

  } | C.ExternalServicesConfig,
}
