variable "environment" {}
variable "namespace" {}
variable "region" {}
variable "out_dir" {
  type    = string
  default = "../../out"
}

resource "random_id" "suffix" {
  byte_length = 8
}


resource "digitalocean_custom_image" "talos" {
  name = "talos"
  url = "https://github.com/siderolabs/talos/releases/download/v1.4.3/digital-ocean-amd64.raw.gz"
  # this gets reset by DigitalOcean otherwise
  distribution = "Unknown OS"
  regions = [var.region]
}

resource "digitalocean_vpc" "main" {
  name = "talos"
  region = var.region 
  # Note: This is VERY CAREFULLY chosen to avoid conflict with k8s and cilium
  ip_range = "192.168.0.0/16"
}

module "digitalocean_talos_cluster" {
  source = "../../terraform_modules/digitalocean_talos_cluster"

  talos_cluster_name = "distrust"
  talos_image = digitalocean_custom_image.talos.image_id
  talos_config_directory = "talos"
  control_plane_pool = {
    count = 1,
    size = "s-4vcpu-8gb",
  }
  worker_pools = [{
    name = "primary",
    count = 2,
    size = "s-2vcpu-4gb",
  }]
  vpc_id = digitalocean_vpc.main.id
  digitalocean_region = var.region 
}

module "digitalocean_database_cluster" {
  source = "../../terraform_modules/digitalocean_database_cluster"

  cluster_name = "distrust"
  db_engine = "pg"
  db_version = "15"
  size = "db-s-1vcpu-2gb"
  node_count = 1

  databases = [{
    name = "keycloak",
    create_default_superuser = true,
  }, {
    name = "forgejo",
    create_default_superuser = true,
  }, {
    # We're creating this database, but then need to delete and recreate manually with LOCALE=C. Otherwise synapse won't work
    # CREATE DATABASE synapse WITH template=template0 owner=doadmin locale="C" encoding=UTF8;
    # GRANT ALL ON DATABASE synapse TO synapse;
    name = "synapse",
    create_default_superuser = true,
  }, {
    name = "telegram",
    create_default_superuser = true,
  }, {
    name = "mautrix_slack",
    create_default_superuser = true,
  }, {
    name = "matrix_slack_appservice",
    create_default_superuser = true,
  }, {
    name = "media_repo",
    create_default_superuser = true,
  }]

  vpc_id = digitalocean_vpc.main.id
  digitalocean_region = var.region 
}

# Crater App requires MySQL currently, when it adds PG support we should migrate
# 
module "digitalocean_mysql_database_cluster" {
  source = "../../terraform_modules/digitalocean_database_cluster"

  cluster_name = "distrust-mysql"
  db_engine = "mysql"
  dbcli_name = "mariadb"
  db_version = "8"
  size = "db-s-1vcpu-1gb"
  node_count = 1

  databases = [{
    name = "crater",
    create_default_superuser = true,
  }]

  vpc_id = digitalocean_vpc.main.id
  digitalocean_region = var.region 
}

resource "digitalocean_spaces_bucket" "matrix_media_repo" {
  name = "${var.namespace}-${var.environment}-distrust-media-repo"
  region = var.region
}

locals {
  database_host = module.digitalocean_database_cluster.database_cluster.private_host
  database_port = module.digitalocean_database_cluster.database_cluster.port
  database_jdbc_uri_prefix = join("", [
    "jdbc:postgresql://",
    module.digitalocean_database_cluster.database_cluster.private_host,
    ":",
    module.digitalocean_database_cluster.database_cluster.port,
  ])
}


# `jq .database_users.value.forgejo | sops --encrypt`
output "database_users" {
  value = {
    for db_user in concat(module.digitalocean_database_cluster.database_users, module.digitalocean_mysql_database_cluster.database_users):
    db_user.name => {
      apiVersion = "v1",
      kind = "Secret",
      metadata = {
        name = "database-configuration",
      },
      stringData = {
        name = db_user.name,
        dbname = db_user.name,
        host = local.database_host,
        port = tostring(local.database_port),
        password = db_user.password,
        # Forgejo, they call it "host"
        address = join(":", [local.database_host, local.database_port]),
        # Keycloak
        jdbc_url = "${local.database_jdbc_uri_prefix}/${db_user.name}?sslmode=require",
      }
    }
  }
  sensitive = true
}

output "database" {
  value = module.digitalocean_database_cluster.database_cluster
  sensitive = true
}

output "mysql_database" {
  value = module.digitalocean_mysql_database_cluster.database_cluster
  sensitive = true
}

output "vpc_id" {
  value = digitalocean_vpc.main.id
}