locals {
  port            = var.port == "" ? var.engine == "aurora-postgresql" ? "5432" : "3306" : var.port
  master_password = var.password == "" ? random_password.master_password.result : var.password
}

resource "random_password" "master_password" {
  length           = 24
  special          = true
  override_special = "!#$%&*-_=+[]{}<>:?"
}

/*
resource "aws_db_subnet_group" "main" {
  name        = "${var.name_prefix}-dbsubnetgroup"
  description = "Subnet group for Aurora cluster ${var.name_prefix}"
  subnet_ids  = var.subnets

  tags = merge(
    var.common_tags,
    {
      "Name" = "${var.name_prefix}-dbsubnetgroup"
    },
  )
}*/

resource "aws_rds_cluster" "main" {
  global_cluster_identifier           = var.global_cluster_identifier
  cluster_identifier                  = "${var.name_prefix}-${var.name}"
  engine                              = var.engine
  engine_mode                         = var.engine_mode
  engine_version                      = var.engine_version
  kms_key_id                          = var.kms_key_id
  database_name                       = var.database_name
  master_username                     = var.username
  master_password                     = local.master_password
  final_snapshot_identifier           = "${var.final_snapshot_identifier_prefix}-${var.name_prefix}-${random_id.snapshot_identifier.hex}"
  skip_final_snapshot                 = var.skip_final_snapshot
  deletion_protection                 = var.deletion_protection
  backup_retention_period             = var.backup_retention_period
  preferred_backup_window             = var.preferred_backup_window
  preferred_maintenance_window        = var.preferred_maintenance_window
  port                                = local.port
  db_subnet_group_name                = var.db_subnet_group_name
  vpc_security_group_ids              = var.security_groups
  snapshot_identifier                 = var.snapshot_identifier
  storage_encrypted                   = var.storage_encrypted
  apply_immediately                   = var.apply_immediately
  db_cluster_parameter_group_name     = var.db_cluster_parameter_group_name
  iam_database_authentication_enabled = var.iam_database_authentication_enabled
  iam_roles                           = var.iam_roles
  copy_tags_to_snapshot               = var.copy_tags_to_snapshot

  enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports

  tags = merge(var.common_tags, { Name = "${var.name_prefix}-${var.name}" })
  lifecycle {
    ignore_changes = [
      snapshot_identifier,
      master_password,
      iam_roles,
      engine_version
    ]
  }
}

resource "aws_rds_cluster_instance" "main" {
  identifier                      = "${var.name_prefix}-${var.name}-master"
  cluster_identifier              = aws_rds_cluster.main.id
  engine                          = var.engine
  engine_version                  = var.engine_version
  instance_class                  = var.master_instance_type == "" ? var.instance_type : var.master_instance_type
  publicly_accessible             = var.publicly_accessible
  db_subnet_group_name            = var.db_subnet_group_name
  db_parameter_group_name         = var.db_parameter_group_name
  preferred_maintenance_window    = var.preferred_maintenance_window
  apply_immediately               = var.apply_immediately
  monitoring_role_arn             = var.monitoring_role_arn
  monitoring_interval             = var.monitoring_interval
  auto_minor_version_upgrade      = var.auto_minor_version_upgrade
  promotion_tier                  = 1
  performance_insights_enabled    = var.performance_insights_enabled
  performance_insights_kms_key_id = var.performance_insights_kms_key_id
  copy_tags_to_snapshot           = var.copy_tags_to_snapshot

  tags = merge(var.common_tags, { Name = "${var.name_prefix}-${var.name}" })

  lifecycle {
    ignore_changes = [engine_version]
  }
}

resource "aws_rds_cluster_instance" "replica" {
  count = var.replica_scale_enabled ? var.replica_scale_min : var.replica_count

  identifier                      = "${var.name_prefix}-${var.name}-replica-${count.index + 2}"
  cluster_identifier              = aws_rds_cluster.main.id
  engine                          = var.engine
  engine_version                  = var.engine_version
  instance_class                  = var.instance_type
  publicly_accessible             = var.publicly_accessible
  db_subnet_group_name            = var.db_subnet_group_name
  db_parameter_group_name         = var.db_parameter_group_name
  preferred_maintenance_window    = var.preferred_maintenance_window
  apply_immediately               = var.apply_immediately
  monitoring_role_arn             = var.monitoring_role_arn
  monitoring_interval             = var.monitoring_interval
  auto_minor_version_upgrade      = var.auto_minor_version_upgrade
  promotion_tier                  = count.index + 2
  performance_insights_enabled    = var.performance_insights_enabled
  performance_insights_kms_key_id = var.performance_insights_kms_key_id
  copy_tags_to_snapshot           = var.copy_tags_to_snapshot

  tags = merge(var.common_tags, { Name = "${var.name_prefix}-${var.name}" })

  lifecycle {
    ignore_changes = [engine_version]
  }
}

resource "random_id" "snapshot_identifier" {
  keepers = {
    id = var.name_prefix
  }
  byte_length = 4
}

resource "aws_appautoscaling_target" "read_replica_count" {
  count = var.replica_scale_enabled ? 1 : 0

  max_capacity       = var.replica_scale_max
  min_capacity       = var.replica_scale_min
  resource_id        = "cluster:${aws_rds_cluster.main.cluster_identifier}"
  scalable_dimension = "rds:cluster:ReadReplicaCount"
  service_namespace  = "rds"
}

resource "aws_appautoscaling_policy" "autoscaling_read_replica_count" {
  count = var.replica_scale_enabled ? 1 : 0

  name               = "target-metric"
  policy_type        = "TargetTrackingScaling"
  resource_id        = "cluster:${aws_rds_cluster.main.cluster_identifier}"
  scalable_dimension = "rds:cluster:ReadReplicaCount"
  service_namespace  = "rds"

  target_tracking_scaling_policy_configuration {
    predefined_metric_specification {
      predefined_metric_type = "RDSReaderAverageCPUUtilization"
    }

    scale_in_cooldown  = var.replica_scale_in_cooldown
    scale_out_cooldown = var.replica_scale_out_cooldown
    target_value       = var.replica_scale_cpu
  }

  depends_on = [aws_appautoscaling_target.read_replica_count]
}

