locals {
  persona            = var.persona
  target_cloud       = var.target_cloud
  target_region      = var.target_region
  target_account     = var.target_account
  aws_profile        = var.aws_profile
  aws_source_profile = var.aws_source_profile

  owner        = lower(trimspace(var.owner))
  session_name = trimspace(var.session_name)

  common_tags = merge(var.tags, {
    "cp9-owner"   = local.owner
    "cp9-session" = local.session_name
    "cp9-managed" = "terraform-substrate"
  })

  iam_enabled                      = var.iam_enabled
  developer_role_name              = var.developer_role_name
  developer_role_arn               = trimspace(var.developer_role_arn) != "" ? var.developer_role_arn : "arn:aws:iam::${local.target_account}:role/${local.developer_role_name}"
  developer_boundary_policy_arn    = trimspace(var.developer_boundary_policy_arn) != "" ? var.developer_boundary_policy_arn : "arn:aws:iam::${local.target_account}:policy/cp9-developer-boundary"
  developer_power_policy_arn       = trimspace(var.developer_power_policy_arn) != "" ? var.developer_power_policy_arn : "arn:aws:iam::${local.target_account}:policy/cp9-developer-power"
  starter_node_boundary_policy_arn = trimspace(var.starter_node_boundary_policy_arn) != "" ? var.starter_node_boundary_policy_arn : local.developer_boundary_policy_arn
  developer_assumed_role_arn_regex = "^arn:aws:sts::${local.target_account}:assumed-role/${local.developer_role_name}/.+$"
  developer_trust_policy           = jsondecode(data.aws_iam_role.developer.assume_role_policy)
  developer_assume_with_tags_statements = [
    for statement in local.developer_trust_policy.Statement : statement
    if contains(try(tolist(statement.Principal.AWS), [tostring(statement.Principal.AWS)], []), "arn:aws:iam::${local.target_account}:root") &&
    contains(try(tolist(statement.Action), [tostring(statement.Action)], []), "sts:AssumeRole") &&
    contains(try(tolist(statement.Action), [tostring(statement.Action)], []), "sts:TagSession") &&
    alltrue([
      for key in ["cp9-owner", "cp9-session"] :
      try(statement.Condition.Null["aws:RequestTag/${key}"], "") == "false"
    ]) &&
    alltrue([
      for key in ["cp9-owner", "cp9-session"] :
      contains(try(tolist(statement.Condition["ForAllValues:StringEquals"]["aws:TagKeys"]), []), key)
    ])
  ]
  developer_assume_with_tags_statement       = try(local.developer_assume_with_tags_statements[0], {})
  developer_assume_with_tags_actions         = try(tolist(local.developer_assume_with_tags_statement.Action), [tostring(local.developer_assume_with_tags_statement.Action)], [])
  developer_assume_with_tags_condition       = try(local.developer_assume_with_tags_statement.Condition, {})
  developer_assume_with_tags_null_conditions = try(local.developer_assume_with_tags_condition.Null, {})
  developer_allowed_tag_keys                 = try(tolist(local.developer_assume_with_tags_condition["ForAllValues:StringEquals"]["aws:TagKeys"]), [])
  trusted_principal_arns                     = [local.developer_role_arn]
  remote_ec2_k3d_enabled                     = var.remote_ec2_k3d_enabled
  o11y_platform_enabled                      = local.remote_ec2_k3d_enabled && local.persona == "premium"
  o11y_platform_bucket                       = substr("${local.session_name}-o11y-${local.target_account}", 0, 63)
  remote_runtime_role_name                   = "cp9-${local.session_name}-remote-runtime"
  remote_runtime_profile_name                = local.remote_runtime_role_name
  remote_runtime_role_arn                    = "arn:aws:iam::${local.target_account}:role/${local.remote_runtime_role_name}"
  dataplane_accounts                         = length(var.dataplane_accounts) > 0 ? var.dataplane_accounts : [local.target_account]
  dataplane_role_name                        = var.dataplane_role_name
  billing_sqs_arn                            = trimspace(var.billing_sqs_arn)
  route53_enabled                            = var.route53_enabled
  source_ecr_profile                         = var.source_ecr_profile
  source_ecr_account_id                      = var.source_ecr_account_id
  source_ecr_region                          = var.source_ecr_region

  workload_role_name             = "cp9-${local.session_name}-workload"
  workload_policy_name           = "cp9-${local.session_name}-workload"
  dedicated_scoped_policy_name   = "cp9-${local.session_name}-dedicated-scoped"
  premium_dataplane_role_enabled = local.iam_enabled && local.persona == "premium"
  dataplane_manager_role_name    = "cp9-${local.session_name}-dataplane-manager"
  dataplane_manager_policy_name  = "cp9-${local.session_name}-dataplane-manager"
  premium_metering_enabled       = local.premium_dataplane_role_enabled
  metering_bucket_name           = "${local.session_name}-metering-${local.target_account}"
  metering_writer_role_name      = "cp9-${local.session_name}-metering-writer"
  metering_read_write_role_name  = "cp9-${local.session_name}-metering-read-write"
  # Keep this independent from aws_iam_role.metering_read_write. The dataplane
  # manager policy must grant AssumeRole on it while that role's trust policy
  # depends on the dataplane manager role.
  metering_read_write_role_arn = "arn:aws:iam::${local.target_account}:role/${local.metering_read_write_role_name}"
  dataplane_assume_role_arns = [
    for account in local.dataplane_accounts : "arn:aws:iam::${account}:role/${local.dataplane_role_name}"
  ]
  premium_eks_nodegroup_service_role_arn      = "arn:aws:iam::${local.target_account}:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup"
  premium_eks_nodegroup_service_role_name_arn = "arn:aws:iam::${local.target_account}:role/AWSServiceRoleForAmazonEKSNodegroup"
  dedicated_crossplane_enabled                = var.dedicated_crossplane_enabled
  dedicated_crossplane_iam_role_arns = [
    "arn:aws:iam::${local.target_account}:role/${local.session_name}-*",
    "arn:aws:iam::${local.target_account}:role/dedicated-${local.session_name}-*",
    "arn:aws:iam::${local.target_account}:role/aws-service-role/eks-nodegroup.amazonaws.com/AWSServiceRoleForAmazonEKSNodegroup",
  ]
  dedicated_crossplane_ticdc_role_arns = [
    "arn:aws:iam::${local.target_account}:role/ticdc-dedica-*",
  ]
  dedicated_crossplane_iam_policy_arns = [
    "arn:aws:iam::${local.target_account}:policy/${local.session_name}-*",
    "arn:aws:iam::${local.target_account}:policy/dedicated-${local.session_name}-*",
  ]
  dedicated_crossplane_ticdc_policy_arns = [
    "arn:aws:iam::${local.target_account}:policy/ticdc-dedica-*-ticdc-node-role-permission",
  ]
  dedicated_crossplane_iam_instance_profile_arns = [
    "arn:aws:iam::${local.target_account}:instance-profile/dedicated-${local.session_name}-*",
  ]
  dedicated_crossplane_ticdc_instance_profile_arns = [
    "arn:aws:iam::${local.target_account}:instance-profile/ticdc-dedica-*",
  ]
  dedicated_crossplane_launch_template_arns = [
    "arn:aws:ec2:${local.target_region}:${local.target_account}:launch-template/*",
  ]
  dedicated_crossplane_kms_key_arns = [
    "arn:aws:kms:${local.target_region}:${local.target_account}:key/*",
  ]
  dedicated_crossplane_autoscaling_group_arns = [
    "arn:aws:autoscaling:${local.target_region}:${local.target_account}:autoScalingGroup:*:autoScalingGroupName/*",
  ]
  dedicated_crossplane_launch_configuration_arns = [
    "arn:aws:autoscaling:${local.target_region}:${local.target_account}:launchConfiguration:*:launchConfigurationName/*${local.session_name}*",
    "arn:aws:autoscaling:${local.target_region}:${local.target_account}:launchConfiguration:*:launchConfigurationName/*dedicated-${local.session_name}*",
  ]
  dedicated_crossplane_vpc_endpoint_arns = [
    "arn:aws:ec2:${local.target_region}:${local.target_account}:vpc-endpoint/*",
  ]
  dedicated_crossplane_vpc_arns = [
    "arn:aws:ec2:${local.target_region}:${local.target_account}:vpc/*",
  ]
  dedicated_crossplane_route_table_arns = [
    "arn:aws:ec2:${local.target_region}:${local.target_account}:route-table/*",
  ]
  dedicated_crossplane_s3_vpc_endpoint_service_name = "com.amazonaws.${local.target_region}.s3"
  dedicated_crossplane_request_tag_keys = [
    "Name",
    # The dedicated regional stack tags per-cluster crossplane resources (e.g. the
    # cluster KMS key) with "cluster"=<clusterId>; without it the ForAllValues
    # aws:TagKeys guard rejects CreateKey/TagResource and the create stalls on
    # "wait for kms key ready".
    "cluster",
    # The community crossplane-contrib AWS provider (keys.kms.aws.crossplane.io,
    # unlike the upbound providers) stamps every managed resource with these
    # default tags, so they must be allowed or its CreateKey/TagResource is denied.
    "crossplane-kind",
    "crossplane-name",
    "crossplane-providerconfig",
    "cp9-managed",
    "cp9-owner",
    "cp9-session",
    "cp9-ttl",
    "environment",
    "project",
    "servicetype",
    "tenant",
    "tidbcloud.com/nodegroup-name",
    "usedby",
  ]

  metadb_enabled  = var.metadb_enabled
  metadb_host     = trimspace(var.metadb_host)
  metadb_port     = var.metadb_port
  metadb_database = var.metadb_database
  metadb_user     = var.metadb_username
  cluster_certificates_storage_bucket = substr(
    replace(lower("${local.session_name}-cluster-certificates"), "_", "-"),
    0,
    63,
  )

  starter_remote_eks_enabled            = var.starter_remote_eks_enabled
  starter_remote_source_images_enabled  = local.starter_remote_eks_enabled || local.persona == "premium"
  starter_infra_cluster_enabled         = var.starter_infra_cluster_enabled || local.starter_remote_eks_enabled
  starter_remote_eks_cluster_name       = trimspace(var.starter_remote_eks_cluster_name) != "" ? trimspace(var.starter_remote_eks_cluster_name) : "cp9-${local.session_name}-starter-regional"
  starter_remote_eks_kubernetes_version = var.starter_remote_eks_kubernetes_version
  starter_remote_eks_node_instance_type = var.starter_remote_eks_node_instance_type
  starter_remote_eks_node_count         = var.starter_remote_eks_node_count
  starter_remote_eks_node_groups        = var.starter_remote_eks_node_groups
  starter_dm_storage_bucket             = substr(replace(lower("${local.session_name}-${local.target_region}-dm"), "_", "-"), 0, 63)
  starter_stashing_area_bucket          = substr(replace(lower("${local.session_name}-${local.target_region}-stashing-area"), "_", "-"), 0, 63)
  starter_serverless_storage_bucket     = substr(replace(lower("cp9-${local.session_name}-starter-cse"), "_", "-"), 0, 63)
  starter_serverless_storage_prefix     = "starter/${local.session_name}/tidb-serverless"

  starter_o11y_stub_enabled                 = var.starter_o11y_stub_enabled
  starter_o11y_stub_function_name           = "cp9-${local.session_name}-starter-o11y"
  starter_o11y_stub_role_name               = "cp9-${local.session_name}-starter-o11y-lambda"
  starter_o11y_stub_evidence_table_name     = "cp9-${local.session_name}-starter-o11y-evidence"
  starter_o11y_stub_script                  = var.starter_o11y_stub_script
  starter_infra_cluster_table_name          = "cp9-${local.session_name}-starter-infra-cluster"
  starter_infra_cluster_event_function_name = "cp9-${local.session_name}-starter-cluster-events"
  starter_infra_cluster_event_role_name     = "cp9-${local.session_name}-starter-cluster-events-lambda"
}
