data "aws_caller_identity" "current" {}

resource "aws_backup_vault" "efs" {
  name        = local.name_prefix
  kms_key_arn = aws_kms_key.efs.arn

  tags = local.tags
}

resource "aws_backup_vault_policy" "efs" {
  backup_vault_name = aws_backup_vault.efs.name
  policy            = data.aws_iam_policy_document.efs_vault_policy.json
}

data "aws_iam_policy_document" "efs_vault_policy" {
  # checkov:skip=CKV_AWS_111:Ensure IAM policies does not allow write access without constraints
  statement {
    actions   = ["backup:CopyIntoBackupVault"]
    resources = ["*"]
    principals {
      type        = "AWS"
      identifiers = var.copy_into_principals
    }
  }
}

resource "aws_kms_key" "efs" {
  description             = "${local.name_prefix}-kms-key"
  enable_key_rotation     = true
  deletion_window_in_days = 30

  tags = local.tags
}

resource "aws_kms_alias" "efs" {
  name          = "alias/${local.name_prefix}-kms-key"
  target_key_id = aws_kms_key.efs.id
}

resource "aws_backup_plan" "efs" {
  count = var.create_backup_plan ? 1 : 0

  name = "${local.name_prefix}-plan"

  rule {
    rule_name           = "default_rule"
    target_vault_name   = aws_backup_vault.efs.name
    schedule            = var.default_rule_schedule
    recovery_point_tags = local.tags
    start_window        = var.default_rule_start_window_minutes
    completion_window   = var.default_rule_completion_window_minutes

    lifecycle {
      cold_storage_after = var.default_rule_cold_storage_after_days
      delete_after       = var.default_rule_delete_after_days
    }

    copy_action {
      destination_vault_arn = var.enable_backup_copy ? var.destination_vault_arn : null
    }
  }

  tags = local.tags
}

resource "aws_backup_selection" "efs" {
  count = var.create_backup_plan ? 1 : 0

  iam_role_arn = aws_iam_role.efs_backup_role.arn
  name         = "${local.name_prefix}-selection"
  plan_id      = aws_backup_plan.efs[0].id

  dynamic "selection_tag" {
    for_each = var.backup_selection_type == "tag" ? [var.default_rule_tag] : []
    content {
      key   = var.default_rule_tag.key
      type  = "STRINGEQUALS"
      value = var.default_rule_tag.value
    }
  }

  resources = var.backup_selection_type == "arn" ? var.resource_arns : []
}

data "aws_iam_policy_document" "assume_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["backup.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "efs_backup_role" {
  assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
  name               = "${local.name_prefix}-role"

  tags = local.tags
}

resource "aws_iam_role_policy_attachment" "efs_backup_policy_attachment" {
  policy_arn = aws_iam_policy.efs_backup_policy.arn
  role       = aws_iam_role.efs_backup_role.id
}

resource "aws_iam_policy" "efs_backup_policy" {
  policy = data.aws_iam_policy_document.efs_backup_policy_document.json
  name   = "${local.name_prefix}-policy"

  tags = local.tags
}

data "aws_iam_policy_document" "efs_backup_policy_document" {
  # checkov:skip=CKV_AWS_111:Ensure IAM policies does not allow write access without constraints
  statement {
    actions = [
      "elasticfilesystem:DescribeFileSystems",
      "tag:GetResources",

    ]
    resources = ["*"]
  }

  statement {
    actions = [
      "kms:DescribeKey",
    ]
    resources = [aws_kms_key.efs.arn]
  }

  statement {
    actions = [
      "backup:DescribeBackupVault",
      "backup:CopyIntoBackupVault"
    ]
    resources = [
      "arn:aws:backup:*:*:backup-vault:*"
    ]
  }

  statement {
    actions = [
      "kms:Decrypt",
      "kms:GenerateDataKey"
    ]
    resources = [aws_kms_key.efs.arn]

    condition {
      test     = "StringLike"
      variable = "kms:ViaService"
      values   = ["elasticfilesystem.*.amazonaws.com"]
    }
  }

  statement {
    actions   = ["kms:CreateGrant"]
    resources = [aws_kms_key.efs.arn]

    condition {
      test     = "Bool"
      values   = ["true"]
      variable = "kms:GrantIsForAWSResource"
    }
  }

  statement {
    actions = [
      "elasticfilesystem:Backup",
      "elasticfilesystem:DescribeTags"
    ]
    resources = ["arn:aws:elasticfilesystem:*:*:file-system/*"]
  }

  statement {
    actions = [
      "backup:CopyFromBackupVault"
    ]
    resources = ["*"]
  }

  statement {
    actions = [
      "backup:TagResource"
    ]
    resources = [
      "arn:aws:backup:*:*:recovery-point:*"
    ]
  }
}
