# EFS File System =============================================================

# Security Group ---------------------------------------------------------------

resource "aws_security_group" "efs" {
  name        = "${var.name}-sg"
  description = "Controls NFS access to EFS file system: ${var.name}."
  vpc_id      = var.vpc_id

  tags = merge(var.tags, local.module_tags, {
    resource-type = "security-group"
    Name          = "${var.name}-sg"
  })
}

resource "aws_vpc_security_group_ingress_rule" "nfs_sg" {
  for_each = toset(var.allowed_security_group_ids)

  security_group_id            = aws_security_group.efs.id
  description                  = "NFS from ${each.value}."
  from_port                    = 2049
  to_port                      = 2049
  ip_protocol                  = "tcp"
  referenced_security_group_id = each.value

  tags = merge(var.tags, local.module_tags, {
    resource-type = "sg-ingress-rule"
    Name          = "${var.name}-igr"
  })
}

resource "aws_vpc_security_group_egress_rule" "all" {
  security_group_id = aws_security_group.efs.id
  description       = "Allow all egress."
  ip_protocol       = "-1"
  cidr_ipv4         = "0.0.0.0/0"

  tags = merge(var.tags, local.module_tags, {
    resource-type = "sg-egress-rule"
    Name          = "${var.name}-egr"
  })
}

# File system ------------------------------------------------------------------

resource "aws_efs_file_system" "this" {
  performance_mode                = var.performance_mode
  throughput_mode                 = var.throughput_mode
  provisioned_throughput_in_mibps = var.provisioned_throughput_mibps
  encrypted                       = true
  kms_key_id                      = var.kms_key_id

  dynamic "lifecycle_policy" {
    for_each = var.lifecycle_policies
    content {
      transition_to_ia                    = lifecycle_policy.value.transition_to_ia
      transition_to_primary_storage_class = lifecycle_policy.value.transition_to_primary_storage_class
    }
  }

  tags = merge(var.tags, local.module_tags, {
    resource-type = "efs-file-system"
    Name          = var.name
  })

  lifecycle {
    # prevent_destroy = true
  }
}

# File system policy -----------------------------------------------------------

resource "aws_efs_file_system_policy" "this" {
  for_each = var.policy != null ? { policy = true } : {}

  file_system_id = aws_efs_file_system.this.id
  policy         = var.policy
}

# Mount targets ----------------------------------------------------------------

resource "aws_efs_mount_target" "this" {
  for_each = local.subnet_map

  file_system_id  = aws_efs_file_system.this.id
  subnet_id       = each.value
  security_groups = [aws_security_group.efs.id]
}

# Access points ----------------------------------------------------------------

resource "aws_efs_access_point" "this" {
  for_each = var.access_points

  file_system_id = aws_efs_file_system.this.id

  posix_user {
    uid = each.value.posix_user_uid
    gid = each.value.posix_user_gid
  }

  root_directory {
    path = each.value.root_path

    creation_info {
      owner_uid   = each.value.owner_uid
      owner_gid   = each.value.owner_gid
      permissions = each.value.permissions
    }
  }

  tags = merge(var.tags, local.module_tags, {
    resource-type = "efs-access-point"
    Name          = "${var.name}-${each.key}"
  })
}

# Replication ------------------------------------------------------------------

resource "aws_efs_replication_configuration" "this" {
  for_each = var.replication_destination_region != null ? { replication = true } : {}

  source_file_system_id = aws_efs_file_system.this.id

  destination {
    region = var.replication_destination_region
  }
}
