# Creates the KMS key
resource "aws_kms_key" "kms_key" {
  count = var.kms_key_enabled ? 1 : 0

  enable_key_rotation = true

  tags = local.tags
}

resource "aws_kms_alias" "kms_alias" {
  count = var.kms_key_enabled ? 1 : 0

  name          = "alias/${var.env}_${var.kms_key_name}"
  target_key_id = aws_kms_key.kms_key[count.index].key_id
}

data "aws_iam_policy_document" "kms_key_policy" {
  # checkov:skip=CKV_AWS_111: It is a KMS key policy, so it applies only to a specific key.
  # checkov:skip=CKV_AWS_109: The same as above.
  override_policy_documents = var.kms_key_policy_overrides

  statement {
    sid    = "Enable IAM policies"
    effect = "Allow"

    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
    }

    actions   = ["kms:*"]
    resources = ["*"]
  }

  # If this bucket is the destination of a replication configuration which includes KMS-encrypted objects, grant the replication role access to the KMS key
  dynamic "statement" {
    for_each = [for rule in var.apply_replication_destination_configuration : rule if rule.grant_kms_access]

    content {
      effect = "Allow"

      actions = [
        "kms:Encrypt",
        "kms:GenerateDataKey"
      ]

      principals {
        type = "AWS"
        identifiers = [
          statement.value.replication_source_iam_role_arn
        ]
      }

      condition {
        test     = "StringLike"
        values   = ["s3.${aws_s3_bucket.bucket.region}.amazonaws.com"]
        variable = "kms:ViaService"
      }

      condition {
        test = "StringLike"
        values = [
          aws_s3_bucket.bucket.arn,
          "${aws_s3_bucket.bucket.arn}/*"
        ]
        variable = "kms:EncryptionContext:aws:s3:arn"
      }

      resources = ["*"]
    }
  }
}

resource "aws_kms_key_policy" "kms_key_policy" {
  count = var.kms_key_enabled ? 1 : 0

  policy = data.aws_iam_policy_document.kms_key_policy.json
  key_id = aws_kms_key.kms_key[0].key_id
}
