# Hetzner Cloud Infrastructure for {{ project_name }}
# Generated by Prism - https://github.com/prism-framework/prism

provider "hcloud" {
  token = var.hcloud_token
}

# SSH Key
resource "hcloud_ssh_key" "deploy_key" {
  name       = "{{ project_name }}-deploy"
  public_key = var.ssh_public_key
}

# Private Network
resource "hcloud_network" "main" {
  name     = "{{ project_name }}-network"
  ip_range = "{{ hetzner.private_network_ip_range }}"
}

resource "hcloud_network_subnet" "main" {
  network_id   = hcloud_network.main.id
  type         = "cloud"
  network_zone = "{{ hetzner.network_zone }}"
  ip_range     = "10.0.1.0/24"
}

# Firewall
resource "hcloud_firewall" "main" {
  name = "{{ project_name }}-firewall"

{% for rule in hetzner.firewall_rules %}
  rule {
    direction   = "in"
    protocol    = "{{ rule.protocol }}"
    port        = "{{ rule.port }}"
    source_ips  = ["0.0.0.0/0", "::/0"]
    description = "{{ rule.description }}"
  }
{% endfor %}

  # Allow all outbound TCP
  rule {
    direction       = "out"
    protocol        = "tcp"
    port            = "1-65535"
    destination_ips = ["0.0.0.0/0", "::/0"]
  }

  # Allow all outbound UDP
  rule {
    direction       = "out"
    protocol        = "udp"
    port            = "1-65535"
    destination_ips = ["0.0.0.0/0", "::/0"]
  }

  # Allow ICMP outbound
  rule {
    direction       = "out"
    protocol        = "icmp"
    destination_ips = ["0.0.0.0/0", "::/0"]
  }

  # Allow ICMP inbound (ping)
  rule {
    direction   = "in"
    protocol    = "icmp"
    source_ips  = ["0.0.0.0/0", "::/0"]
    description = "ICMP"
  }
}

# Staging Server
module "staging" {
  source = "./modules/server"
  count  = var.deploy_staging ? 1 : 0

  project_name       = "{{ project_name }}"
  environment        = "staging"
  server_type        = var.staging_server_type
  location           = var.location
  ssh_key_ids        = [hcloud_ssh_key.deploy_key.id]
  subnet_id          = hcloud_network_subnet.main.id
  firewall_ids       = [hcloud_firewall.main.id]
  cloud_init_file    = templatefile("${path.module}/cloud-init/user-data.yml", {
    ssh_public_key = var.ssh_public_key
  })
  enable_floating_ip = false

  labels = {
    environment = "staging"
    project     = "{{ project_name }}"
    managed_by  = "terraform"
  }
}

# Production Server
module "production" {
  source = "./modules/server"
  count  = var.deploy_production ? 1 : 0

  project_name       = "{{ project_name }}"
  environment        = "production"
  server_type        = var.production_server_type
  location           = var.location
  ssh_key_ids        = [hcloud_ssh_key.deploy_key.id]
  subnet_id          = hcloud_network_subnet.main.id
  firewall_ids       = [hcloud_firewall.main.id]
  cloud_init_file    = templatefile("${path.module}/cloud-init/user-data.yml", {
    ssh_public_key = var.ssh_public_key
  })
  enable_floating_ip = var.production_floating_ip

  labels = {
    environment = "production"
    project     = "{{ project_name }}"
    managed_by  = "terraform"
  }
}

# Staging Data Volume
module "staging_volume" {
  source = "./modules/volume"
  count  = var.deploy_staging ? 1 : 0

  name      = "{{ project_name }}-staging-data"
  size      = var.staging_volume_size
  location  = var.location
  server_id = module.staging[0].server_id

  labels = {
    environment = "staging"
    project     = "{{ project_name }}"
    purpose     = "postgresql"
  }
}

# Production Data Volume
module "production_volume" {
  source = "./modules/volume"
  count  = var.deploy_production ? 1 : 0

  name      = "{{ project_name }}-production-data"
  size      = var.production_volume_size
  location  = var.location
  server_id = module.production[0].server_id

  labels = {
    environment = "production"
    project     = "{{ project_name }}"
    purpose     = "postgresql"
  }
}
