data "aws_secretsmanager_secret" "this" {
  for_each = toset(var.secrets)
  name     = each.value
}

locals {
  kms_key_arns = [for secret in data.aws_secretsmanager_secret.this : secret.kms_key_id if secret.kms_key_id != ""]

  key_to_secrets_map = {
    for arn in local.kms_key_arns : arn => concat(
      [for s in data.aws_secretsmanager_secret.this : s.arn if s.kms_key_id == arn],
    )
  }

  secrets_read_actions = [
    "secretsmanager:ListSecretVersionIds",
    "secretsmanager:GetSecretValue",
    "secretsmanager:DescribeSecret",
  ]

  secrets_write_actions = [
    "secretsmanager:UpdateSecretVersionStage",
    "secretsmanager:PutSecretValue"
  ]

  kms_read_actions = [
    "kms:Decrypt",
    "kms:DescribeKey",
  ]

  kms_write_actions = [
    "kms:ReEncrypt*",
    "kms:GenerateDataKey*",
    "kms:Encrypt",
  ]

  secrets_actions = concat(
    (contains(var.action_types, "read") ? local.secrets_read_actions : []),
    (contains(var.action_types, "write") ? local.secrets_write_actions : []),
  )

  kms_actions = concat(
    (contains(var.action_types, "read") ? local.kms_read_actions : []),
    (contains(var.action_types, "write") ? local.kms_write_actions : []),
  )

  sid_suffix = substr(sha256(jsonencode(var.secrets)), 0, 10)
}

data "aws_iam_policy_document" "policy" {
  statement {
    sid       = "AllowSecretActions${local.sid_suffix}"
    actions   = local.secrets_actions
    resources = [for k, v in data.aws_secretsmanager_secret.this : v.arn]
  }

  dynamic "statement" {
    for_each = local.key_to_secrets_map
    content {
      sid     = "AllowKMSActions${local.sid_suffix}${replace(split("/", statement.key)[1], "-", "")}"
      actions = local.kms_actions
      resources = [
        statement.key
      ]
      condition {
        test     = "StringLike"
        variable = "kms:EncryptionContext:SecretARN"
        values   = statement.value
      }
    }
  }
}
