locals {
  name_{{ t.name }} = "{{ t.name }}"
  subscription_name_{{ t.name }} = "{{ t.subscription_name }}"
  management_group_{{ t.name }} = "{{ t.management_group }}"
  category_{{ t.name }} = "{{ t.category }}"
  enforcement_mode_{{ t.name }} = {{ t.enforcement_mode }}
  policy_ids_{{ t.name }} = [{% for service_name, service_policies in t.policy_id_pairs.items() %}
    # -----------------------------------------------------------------------------------------------------------------
    # {{ service_name }}
    # -----------------------------------------------------------------------------------------------------------------{% for policy_id, policy_details in service_policies.items() %}
    "{{ policy_details.short_id }}", # {{ policy_details.display_name }} {% endfor %}
    {% endfor %}
  ]
  policy_definition_map = {
    {% for service_name, service_policies in t.policy_id_pairs.items() -%}
  {% for policy_id, policy_details in service_policies.items() -%}
  "{{ policy_details.display_name }}" = "{{ policy_details.long_id }}",
    {% endfor %}
    {%- endfor -%}
}
}

# ---------------------------------------------------------------------------------------------------------------------
# Conditional data lookups: If the user supplies management group, look up the ID of the management group
# ---------------------------------------------------------------------------------------------------------------------
data "azurerm_management_group" "{{ t.name }}" {
  count = local.management_group_{{ t.name }} != "" ? 1 : 0
  display_name  = local.management_group_{{ t.name }}
}

### If the user supplies subscription, look up the ID of the subscription
data "azurerm_subscriptions" "{{ t.name }}" {
  count                 = local.subscription_name_{{ t.name }} != "" ? 1 : 0
  display_name_contains = local.subscription_name_{{ t.name }}
}

locals {
  scope = local.management_group_{{ t.name }} != "" ? data.azurerm_management_group.{{ t.name }}[0].id : element(data.azurerm_subscriptions.{{ t.name }}[0].subscriptions.*.id, 0)
}

# ---------------------------------------------------------------------------------------------------------------------
# Azure Policy Definition Lookups
# ---------------------------------------------------------------------------------------------------------------------

data "azurerm_policy_definition" "{{ t.name }}_definition_lookups" {
  count = length(local.policy_ids_{{ t.name }})
  name  = local.policy_ids_{{ t.name }}[count.index]
}

# ---------------------------------------------------------------------------------------------------------------------
# Azure Policy Initiative Definition
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_policy_set_definition" "{{ t.name }}" {
  name                  = local.name_{{ t.name }}
  policy_type           = "Custom"
  display_name          = local.name_{{ t.name }}
  description           = local.name_{{ t.name }}
  management_group_name = local.management_group_{{ t.name }} == "" ? null : local.management_group_{{ t.name }}
  metadata = tostring(jsonencode({
    category = local.category_{{ t.name }}
  }))
  {%- for service_name, service_policy_details in t.policy_definition_reference_parameters.items() -%}
  {% for policy_definition_name, policy_definition_details in service_policy_details.items() %}
  policy_definition_reference {
    policy_definition_id = lookup(local.policy_definition_map, "{{ policy_definition_name|normalize_display_name_string }}")
    parameter_values = jsonencode({
      {%- for parameter, parameter_details in policy_definition_details.items() %}
      {%- if parameter_details['parameter_value'] is string -%}
        {{ "\n        " }}{{ parameter_details["parameter_name"] }} = { "value" : {{ parameter_details['parameter_value']|format_parameter_value }} }
      {%- else -%}
        {%- if 'value' not in parameter_details['parameter_value'].keys() -%}
            {{ "\n        " }}{{ parameter_details["parameter_name"] }} = { "value" : {{ parameter_details['parameter_value']['type']|get_placeholder_value_given_type }} }
        {%- else -%}
            {{ "\n        " }}{{ parameter_details["parameter_name"] }} = { "value" : {{ parameter_details['parameter_value']['value']|format_parameter_value }} }
        {%- endif -%}
      {%- endif -%}
{% endfor %}
    })
    reference_id = null
  }
{% endfor %}{%- endfor -%}
}

# ---------------------------------------------------------------------------------------------------------------------
# Azure Policy Assignments
# Apply the Policy Initiative to the specified scope
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_policy_assignment" "{{ t.name }}" {
  name                 = local.name_{{ t.name }}
  policy_definition_id = azurerm_policy_set_definition.{{ t.name }}.id
  scope                = local.scope
  enforcement_mode     = local.enforcement_mode_{{ t.name }}
}


# ---------------------------------------------------------------------------------------------------------------------
# Outputs
# ---------------------------------------------------------------------------------------------------------------------
output "{{ t.name }}_policy_assignment_ids" {
  value       = azurerm_policy_assignment.{{ t.name }}.id
  description = "The IDs of the Policy Assignments."
}

output "{{ t.name }}_scope" {
  value       = local.scope
  description = "The target scope - either the management group or subscription, depending on which parameters were supplied"
}

output "{{ t.name }}_policy_set_definition_id" {
  value       = azurerm_policy_set_definition.{{ t.name }}.id
  description = "The ID of the Policy Set Definition."
}
