variable "wait_on" {
  type        = any
  description = "Resources to wait on"
  default     = true
}

variable "server_ip" {
  type = string
}

variable "ssh_private_key_path" {
  type = string
}

variable "server_domain" {
  type = string
}

# Credentials from existing services
variable "postgres_password" {
  type      = string
  sensitive = true
}

variable "minio_server" {
  type      = string
  sensitive = true
}

variable "minio_access_key" {
  type      = string
  sensitive = true
}

variable "minio_secret_key" {
  type      = string
  sensitive = true
}

variable "rabbitmq_username" {
  type      = string
  sensitive = true
}

variable "rabbitmq_password" {
  type      = string
  sensitive = true
}

# Generate Plane-specific credentials
resource "random_password" "redis_password" {
  length  = 32
  special = false
}

resource "random_password" "secret_key" {
  length  = 64
  special = true
}

module "psql_db" {
  source = "../postgres/tenant"
  
  tenant_name    = "plane"
  admin_username = "postgres"
  admin_password = var.postgres_password
  server_ip      = var.server_ip
  ssh_private_key_path = var.ssh_private_key_path
}

module "aqmp_db" {
  source = "../rabbitmq/tenant"
  
  tenant_name    = "plane"
  admin_username = var.rabbitmq_username
  admin_password = var.rabbitmq_password
  server_ip      = var.server_ip
  ssh_private_key_path = var.ssh_private_key_path
}

module "minio" {
  source = "../minio/tenant"

  name = "plane"
  server = var.minio_server
  access_key = var.minio_access_key
  secret_key = var.minio_secret_key
  tls = true
}

# Deploy the core API service first
module "api" {
  source = "./api"
  wait_on = var.wait_on
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
  
  # Use credentials from existing services
  redis_password   = "" #random_password.redis_password.result
  db_password      = module.psql_db.password
  rabbitmq_password = module.aqmp_db.password

  minio_access_key = module.minio.access_key
  minio_secret_key = module.minio.secret_key
  secret_key       = random_password.secret_key.result
}

# Run database migrations after API is ready
module "migrator" {
  source = "./migrator"
  wait_on = module.api.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
  
  # Use credentials from API module
  db_password      = module.api.db_password
  redis_password   = module.api.redis_password
  rabbitmq_password = module.api.rabbitmq_password
  minio_access_key = module.minio.access_key
  minio_secret_key = module.minio.secret_key
  secret_key       = module.api.secret_key
}

# Start background workers after migrations
module "worker" {
  source = "./worker"
  wait_on = module.migrator.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
  
  # Use credentials from API module
  db_password      = module.api.db_password
  redis_password   = module.api.redis_password
  rabbitmq_password = module.api.rabbitmq_password
  minio_access_key = module.minio.access_key
  minio_secret_key = module.minio.secret_key
  secret_key       = module.api.secret_key
}

module "beat-worker" {
  source = "./beat-worker"
  wait_on = module.migrator.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
  
  # Use credentials from API module
  db_password      = module.api.db_password
  redis_password   = module.api.redis_password
  rabbitmq_password = module.api.rabbitmq_password
  minio_access_key = module.minio.access_key
  minio_secret_key = module.minio.secret_key
  secret_key       = module.api.secret_key
}

# Start web interfaces after API is ready
module "web" {
  source = "./web"
  wait_on = module.api.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
}

module "admin" {
  source = "./admin"
  wait_on = module.api.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
}

module "space" {
  source = "./space"
  wait_on = module.api.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
}

module "live" {
  source = "./live"
  wait_on = module.api.installed
  server_ip = var.server_ip
  server_domain = var.server_domain
  ssh_private_key_path = var.ssh_private_key_path
}

# Aggregate all app URLs
locals {
  app_urls = {
    web    = module.web.app_urls
    admin  = module.admin.app_urls
    space  = module.space.app_urls
    live   = module.live.app_urls
    api    = module.api.app_urls
  }
}

output "app_urls" {
  value = local.app_urls
  description = "All Plane application URLs"
}

output "installed" {
  value = true
  depends_on = [
    module.api.installed,
    module.migrator.installed,
    module.worker.installed,
    module.beat-worker.installed,
    module.web.installed,
    module.admin.installed,
    module.space.installed,
    module.live.installed
  ]
  description = "Whether all Plane services are installed"
}

output "credentials" {
  value = {
    db_password      = module.api.db_password
    redis_password   = module.api.redis_password
    minio_access_key = module.api.minio_access_key
    minio_secret_key = module.api.minio_secret_key
    rabbitmq_password = module.api.rabbitmq_password
    secret_key       = module.api.secret_key
  }
  sensitive = true
  description = "All Plane service credentials"
}

output "main_url" {
  value = "https://plane.${var.server_domain}"
  description = "Main Plane application URL"
}