provider "aws" {
  region  = local.target_region
  profile = local.aws_profile

  default_tags {
    tags = local.common_tags
  }
}

data "aws_caller_identity" "current" {}

data "aws_route53_zone" "cp9" {
  zone_id      = var.cp9_dns_zone_id
  private_zone = false

  lifecycle {
    postcondition {
      condition     = trimsuffix(self.name, ".") == trimsuffix(var.cp9_dns_zone_name, ".")
      error_message = "cp9_dns_zone_id must resolve to cp9_dns_zone_name in the target runtime account."
    }
  }
}

data "aws_iam_role" "developer" {
  name = local.developer_role_name
}

data "aws_iam_policy" "developer_boundary" {
  arn = local.developer_boundary_policy_arn
}

data "aws_iam_policy" "developer_power" {
  arn = local.developer_power_policy_arn
}

resource "terraform_data" "config_guard" {
  input = {
    caller_arn                = data.aws_caller_identity.current.arn
    developer_boundary_policy = local.developer_boundary_policy_arn
    developer_power_policy    = local.developer_power_policy_arn
    developer_role            = local.developer_role_arn
    cp9_dns_zone_id           = data.aws_route53_zone.cp9.zone_id
    cp9_dns_zone_name         = trimsuffix(data.aws_route53_zone.cp9.name, ".")
    owner                     = local.owner
    persona                   = local.persona
    session_name              = local.session_name
    target_cloud              = local.target_cloud
    target_region             = local.target_region
    target_account            = local.target_account
  }

  lifecycle {
    precondition {
      condition     = local.persona == "premium"
      error_message = "This in-repo bootstrap substrate currently supports only the Dev full substrate input family."
    }

    precondition {
      condition     = local.target_cloud == "aws"
      error_message = "cp9-substrate currently supports only target.cloud=aws."
    }

    precondition {
      condition     = local.target_region != ""
      error_message = "target.region is required."
    }

    precondition {
      condition     = data.aws_caller_identity.current.account_id == local.target_account
      error_message = "The active AWS account does not match target_account from cp9 iam_ready."
    }

    precondition {
      condition     = can(regex(local.developer_assumed_role_arn_regex, data.aws_caller_identity.current.arn))
      error_message = "cp9 Terraform must run as arn:aws:iam::${local.target_account}:role/${local.developer_role_name}; configure target.aws.iam.profile to assume cp9-developer."
    }

    precondition {
      condition     = data.aws_iam_role.developer.arn == local.developer_role_arn
      error_message = "Configured cp9 developer role ARN does not match the existing IAM role."
    }

    precondition {
      condition     = data.aws_iam_role.developer.permissions_boundary == local.developer_boundary_policy_arn
      error_message = "cp9 developer role must use arn:aws:iam::${local.target_account}:policy/cp9-developer-boundary as its permissions boundary."
    }

    precondition {
      condition     = length(local.developer_assume_with_tags_statements) == 1
      error_message = "cp9 developer role trust policy must contain exactly one tagged AssumeRole/TagSession statement."
    }

    precondition {
      condition     = contains(local.developer_assume_with_tags_actions, "sts:AssumeRole") && contains(local.developer_assume_with_tags_actions, "sts:TagSession")
      error_message = "cp9 developer role trust policy must allow both sts:AssumeRole and sts:TagSession for tagged local sessions."
    }

    precondition {
      condition = alltrue([
        for key in ["cp9-owner", "cp9-session"] :
        try(local.developer_assume_with_tags_null_conditions["aws:RequestTag/${key}"], "") == "false"
      ])
      error_message = "cp9 developer role trust policy must require cp9-owner and cp9-session request tags."
    }

    precondition {
      condition = alltrue([
        for key in ["cp9-owner", "cp9-session"] :
        contains(local.developer_allowed_tag_keys, key)
      ])
      error_message = "cp9 developer role trust policy must restrict allowed session tag keys to include cp9-owner and cp9-session."
    }

    precondition {
      condition     = data.aws_iam_policy.developer_boundary.arn == local.developer_boundary_policy_arn
      error_message = "cp9 developer boundary policy is missing or does not match the configured ARN."
    }

    precondition {
      condition     = data.aws_iam_policy.developer_power.arn == local.developer_power_policy_arn
      error_message = "cp9 developer power policy is missing or does not match the configured ARN."
    }

    precondition {
      condition     = alltrue([for key in ["cp9-owner", "cp9-session", "cp9-managed", "cp9-ttl"] : contains(keys(local.common_tags), key) && trimspace(local.common_tags[key]) != ""])
      error_message = "cp9 substrate requires cp9-owner, cp9-session, cp9-managed, and cp9-ttl tags."
    }

    precondition {
      condition     = !local.iam_enabled || length(local.trusted_principal_arns) > 0
      error_message = "iam.trusted_principal_arns must contain at least one principal when IAM support is enabled."
    }

    precondition {
      condition     = !local.iam_enabled || length(local.dataplane_accounts) > 0
      error_message = "iam.dataplane_accounts must contain at least one account when IAM support is enabled."
    }

    precondition {
      condition     = !local.metadb_enabled || local.metadb_host != ""
      error_message = "metadb.endpoint.host is required when metadb support is enabled."
    }
  }
}
