terraform {
  required_providers {
    azuread = {
      source  = "hashicorp/azuread"
      version = "~> 3.0"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.58"
    }
  }
}

provider "azurerm" {
  alias           = "dp_0"
  use_cli         = true
  subscription_id = var.dataplane_accounts[0].subscriptionID
  features {}
}

provider "azurerm" {
  alias           = "dp_1"
  use_cli         = true
  subscription_id = try(var.dataplane_accounts[1].subscriptionID, var.dataplane_accounts[0].subscriptionID)
  features {}
}

provider "azurerm" {
  alias           = "dp_2"
  use_cli         = true
  subscription_id = try(var.dataplane_accounts[2].subscriptionID, var.dataplane_accounts[0].subscriptionID)
  features {}
}

variable "env" {
  type = string
}

variable "cloud_region" {
  type = string
}

variable "logical_region_name" {
  type = string
}

variable "dataplane_accounts" {
  type = list(object({
    subscriptionID      = string
    bucketResourceGroup = string
  }))
}

variable "resource_group_name" {
  type = string
}

variable "oidc_issuer" {
  type = string
}

variable "key_vault_id" {
  type = string
}

variable "dns_zone_id" {
  type = string
}

variable "metering_container_scope" {
  type = string
}

variable "tags" {
  type    = map(string)
  default = {}
}

module "cert_manager" {
  source = "../../azure_modules/workload-identity/cert-manager/controlplane"

  env                 = var.env
  cloud_region        = var.cloud_region
  logical_region_name = var.logical_region_name
  resource_group_name = var.resource_group_name
  oidc_issuer         = var.oidc_issuer
  dns_zone_id         = var.dns_zone_id
  tags                = var.tags
}

module "external_secrets_operator" {
  source = "../../azure_modules/workload-identity/external-secrets-operator/controlplane"

  env                 = var.env
  cloud_region        = var.cloud_region
  logical_region_name = var.logical_region_name
  resource_group_name = var.resource_group_name
  oidc_issuer         = var.oidc_issuer
  key_vault_id        = var.key_vault_id
  tags                = var.tags
}

module "dataplane_manager" {
  source = "../../azure_modules/workload-identity/dataplane-manager/controlplane"

  env                 = var.env
  cloud_region        = var.cloud_region
  logical_region_name = var.logical_region_name
  resource_group_name = var.resource_group_name
  oidc_issuer         = var.oidc_issuer
  tags                = var.tags
}

data "azuread_group" "control_plane_services" {
  display_name     = "${var.env}-control-plane-services"
  security_enabled = true
}

resource "null_resource" "wait_for_dataplane_manager_identity" {
  triggers = {
    principal_id = module.dataplane_manager.principal_id
    group_id     = data.azuread_group.control_plane_services.object_id
  }

  provisioner "local-exec" {
    command = "sleep 20"
  }
}

resource "azuread_group_member" "dataplane_manager_admin_group" {
  group_object_id  = data.azuread_group.control_plane_services.object_id
  member_object_id = module.dataplane_manager.principal_id

  depends_on = [null_resource.wait_for_dataplane_manager_identity]
}

locals {
  dp_accounts = length(var.dataplane_accounts)
}

module "dataplane_manager_dp_0" {
  count  = local.dp_accounts > 0 ? 1 : 0
  source = "../../azure_modules/workload-identity/dataplane-manager/dataplane"
  providers = {
    azurerm = azurerm.dp_0
  }

  principal_id               = module.dataplane_manager.principal_id
  bucket_resource_group_name = var.dataplane_accounts[0].bucketResourceGroup
}

module "dataplane_manager_dp_1" {
  count  = local.dp_accounts > 1 ? 1 : 0
  source = "../../azure_modules/workload-identity/dataplane-manager/dataplane"
  providers = {
    azurerm = azurerm.dp_1
  }

  principal_id               = module.dataplane_manager.principal_id
  bucket_resource_group_name = var.dataplane_accounts[1].bucketResourceGroup
}

module "dataplane_manager_dp_2" {
  count  = local.dp_accounts > 2 ? 1 : 0
  source = "../../azure_modules/workload-identity/dataplane-manager/dataplane"
  providers = {
    azurerm = azurerm.dp_2
  }

  principal_id               = module.dataplane_manager.principal_id
  bucket_resource_group_name = var.dataplane_accounts[2].bucketResourceGroup
}

resource "azurerm_role_assignment" "dataplane_manager_metering" {
  scope                = var.metering_container_scope
  role_definition_name = "Storage Blob Data Contributor"
  principal_id         = module.dataplane_manager.principal_id
}

module "metering" {
  source = "../../azure_modules/workload-identity/metering/controlplane"

  env                      = var.env
  cloud_region             = var.cloud_region
  logical_region_name      = var.logical_region_name
  resource_group_name      = var.resource_group_name
  oidc_issuer              = var.oidc_issuer
  metering_container_scope = var.metering_container_scope
  tags                     = var.tags
}

output "cert_manager_client_id" {
  value = module.cert_manager.client_id
}

output "cert_manager_principal_id" {
  value = module.cert_manager.principal_id
}

output "external_secrets_operator_client_id" {
  value = module.external_secrets_operator.client_id
}

output "external_secrets_operator_principal_id" {
  value = module.external_secrets_operator.principal_id
}

output "dataplane_manager_client_id" {
  value = module.dataplane_manager.client_id
}

output "dataplane_manager_principal_id" {
  value = module.dataplane_manager.principal_id
}

output "dataplane_role_assignment_ids" {
  value = compact([
    try(module.dataplane_manager_dp_0[0].role_assignment_id, ""),
    try(module.dataplane_manager_dp_1[0].role_assignment_id, ""),
    try(module.dataplane_manager_dp_2[0].role_assignment_id, ""),
  ])
}

output "dataplane_blob_owner_role_assignment_ids" {
  value = compact([
    try(module.dataplane_manager_dp_0[0].blob_owner_role_assignment_id, ""),
    try(module.dataplane_manager_dp_1[0].blob_owner_role_assignment_id, ""),
    try(module.dataplane_manager_dp_2[0].blob_owner_role_assignment_id, ""),
  ])
}

output "metering_client_id" {
  value = module.metering.client_id
}

output "metering_principal_id" {
  value = module.metering.principal_id
}
