locals {
  tld          = "fourlights.dev"
  cluster_dns  = "neptune.${local.tld}"
  is_installed = true
  node_count   = 1
}

resource "kubernetes_manifest" "traefik-helm-config" {
  manifest = {
    apiVersion = "helm.cattle.io/v1"
    kind       = "HelmChartConfig"
    metadata = {
      name      = "traefik"
      namespace = "kube-system"
    }
    spec = {
      valuesContent = <<EOF
serversTransport:
  forwardingTimeouts:
    dialTimeout: 0
    responseHeaderTimeout: 0
    idleConnTimeout: 0
logs:
  general:
    level: ERROR
ports:
  web:
    proxyProtocol:
      trustedIPs: [ 127.0.0.1/8,10.0.0.0/8 ]
    forwardedHeaders:
      trustedIPs: [ 127.0.0.1/8,10.0.0.0/8 ]
    transport:
      respondingTimeouts:
        writeTimeout: 0
        idleTimeout: 0
        readTimeout: 0
EOF
    }
  }
}

resource "kubernetes_manifest" "preserve-host-middleware" {
  depends_on = [local.is_installed]
  manifest = {
    apiVersion = "traefik.io/v1alpha1"
    kind       = "Middleware"
    metadata = {
      name      = "preserve-host-headers"
      namespace = "default"   # NOTE: Hardcoded by design
    }
    spec = {
      headers = {
        customRequestHeaders = {
          "X-Forwarded-Proto" = "https"
          "X-Forwarded-Port"  = "443"
        }
      }
    }
  }
}

resource "kubernetes_manifest" "https-redirect-middleware" {
  depends_on = [local.is_installed]
  manifest = {
    apiVersion = "traefik.io/v1alpha1"
    kind       = "Middleware"
    metadata = {
      name      = "redirect-to-https"
      namespace = "default"   # NOTE: Hardcoded by design
    }
    spec = {
      redirectScheme = {
        permanent = true
        scheme    = "https"
      }
    }
  }
}

module "homepage" {
  source          = "../../infra/modules/homepage"
  wait_on         = local.is_installed
  k8s_config_yaml = local.k8s_config_yaml

  server_dns   = local.cluster_dns
  service_name = "homepage"
  service_uri  = local.cluster_dns
  namespace    = "homepage"
}

module "minio" {
  source          = "../../infra/modules/minio"
  wait_on         = local.is_installed
  k8s_config_yaml = local.k8s_config_yaml

  server_dns   = local.cluster_dns
  service_name = "storage"
  namespace    = "minio"

  admin_server_dns = local.cluster_dns   # Restricted admin access, access via bridge

  tls          = false
  admin        = true
  ingressClass = "traefik"
  storageSize  = "10Gi"

  displayOnHomepage = true
}

module "mongodb" {
  source          = "../../infra/modules/mongodb"
  wait_on         = local.is_installed
  k8s_config_yaml = local.k8s_config_yaml

  namespace = "mongodb"
  replicas  = local.node_count
}

module "rabbitmq" {
  source          = "../../infra/modules/rabbitmq"
  wait_on         = local.is_installed
  k8s_config_yaml = local.k8s_config_yaml

  server_dns = "local"    # Restricted admin access, access via bridge

  service_name = "rabbitmq"
  namespace    = "rabbitmq"

  tls          = false
  admin        = true
  ingressClass = "traefik"
}

module "postgresql" {
  source = "../../infra/modules/postgresql"

  namespace       = "postgresql"
  k8s_config_yaml = local.k8s_config_yaml
  username        = "bridge"
}

module "zitadel-db" {
  source  = "../../infra/modules/postgresql/tenant"
  wait_on = module.postgresql.installed

  name            = "zitadel"
  root_password   = module.postgresql.root_password
  k8s_config_yaml = local.k8s_config_yaml
}

module "zitadel" {
  source          = "../../infra/modules/zitadel"
  wait_on         = module.zitadel-db.installed
  k8s_config_yaml = local.k8s_config_yaml

  server_dns = local.cluster_dns

  service_name = "zitadel"
  namespace    = "zitadel"

  database_password      = module.zitadel-db.password
  database_root_password = module.postgresql.root_password

  display_on_homepage = true
}

module "zitadel-bootstrap" {
  source = "../../infra/tenants/fourlights/zitadel"

  domain           = module.zitadel.server
  jwt_profile_file = module.zitadel.jwt_profile_file
}

module "redis" {
  source = "../../infra/modules/redis"

  namespace       = "redis"
  k8s_config_yaml = local.k8s_config_yaml
}

module "tenant-365zon" {
  source = "../../infra/tenants/365zon"

  wait_on = module.minio.installed

  org_id           = module.zitadel-bootstrap.org_id
  user_id          = module.zitadel-bootstrap.user_id
  domain           = module.zitadel.server
  jwt_profile_file = module.zitadel.jwt_profile_file

  minio_access_key = module.minio.minio_access_key
  minio_secret_key = module.minio.minio_secret_key
  minio_server     = module.minio.minio_server
  minio_api_uri    = module.minio.minio_api_uri

  mongodb_connection_string  = module.mongodb.connection_string
  rabbitmq_connection_string = module.rabbitmq.connection_string
}

module "zitadel-argocd" {
  source = "../../infra/tenants/argocd/zitadel"

  org_id           = module.zitadel-bootstrap.org_id
  user_id          = module.zitadel-bootstrap.user_id
  domain           = module.zitadel.server
  jwt_profile_file = module.zitadel.jwt_profile_file

  argocd_service_domain = "argocd.${ local.cluster_dns}"
}

module "argocd" {
  source  = "../../infra/modules/argocd"
  wait_on = module.zitadel-argocd.installed

  namespace       = "argocd"
  k8s_config_yaml = local.k8s_config_yaml

  redis_db_start_index = 0
  redis_password       = module.redis.password
  server_dns           = local.cluster_dns

  oauth_uri           = module.zitadel.server
  oauth_client_id     = module.zitadel-argocd.client_id
  oauth_client_secret = module.zitadel-argocd.client_secret
  oauth_redirect_uri  = "https://${module.zitadel.server}/${module.zitadel-argocd.logoutSuffix}"
  oauth_issuer        = "https://${module.zitadel.server}"
}

module "monitoring" {
  source = "../../infra/modules/monitoring"
  wait_on = module.argocd.installed

  namespace = "monitoring"
  k8s_config_yaml = local.k8s_config_yaml

  server_dns           = local.cluster_dns
}

/*
  argocd project
 */

output "argocd-root-password" {
  value     = module.argocd.admin_password
  sensitive = true
}

output "mongodb-connection-string" {
  value     = module.mongodb.connection_string
  sensitive = true
}

output "rabbitmq-connection-string" {
  value     = module.rabbitmq.connection_string
  sensitive = true
}

output "minio-access-key" {
  value     = module.tenant-365zon.minio_access_key
  sensitive = true
}

output "minio-secret-key" {
  value     = module.tenant-365zon.minio_secret_key
  sensitive = true
}

output "minio-root-access-key" {
  value     = module.minio.minio_access_key
  sensitive = true
}

output "minio-root-secret-key" {
  value     = module.minio.minio_secret_key
  sensitive = true
}

output "monitoring" {
  value = module.monitoring.access_instructions
  sensitive = true
}