locals {
  used_connections_metric = var.native_database_integration_enabled && var.rds_engine == "aurora-mysql" ? "mysql.performance.threads_connected" : "aws.rds.database_connections"
}

# Datadog RDS timeboard
resource "datadog_dashboard" "datadog_rds" {
  title       = "${var.environment}-${var.service_name} RDS timeboard"
  description = "Default terraformed timeboard for RDS"
  layout_type = "ordered"

  template_variable {
    prefix           = "dbinstanceidentifier"
    name             = "dbinstanceidentifier"
    available_values = [for i in range(var.cluster_instance_count) : "${var.environment}-${var.service_name}-${i}"]
  }

  widget {
    group_definition {
      title       = "Resource Utilization"
      layout_type = "ordered"

      # Database CPU Utilization (Percentage of CPU utilization)
      widget {
        timeseries_definition {
          title = "CPU Utilization"

          request {
            q = "max:aws.rds.cpuutilization.total{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Memory Usage (Amount of used random access memory)
      widget {
        timeseries_definition {
          title = "Memory Utilization"

          request {
            query {
              metric_query {
                name  = "free_memory"
                query = "max:aws.rds.memory.free{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            query {
              metric_query {
                name  = "cached_memory"
                query = "max:aws.rds.memory.cached{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            query {
              metric_query {
                name  = "buffers_memory"
                query = "max:aws.rds.memory.buffers{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            query {
              metric_query {
                name  = "total_memory"
                query = "max:aws.rds.memory.total{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            formula {
              formula_expression = "total_memory - free_memory - cached_memory - buffers_memory"
              alias              = "Used Memory"
            }
            formula {
              formula_expression = "total_memory"
              alias              = "Total Memory"
              style {
                palette = "grey"
              }
            }
          }
        }
      }

      # Database Storage Utilization (The amount of local storage that is free on an instance)
      widget {
        timeseries_definition {
          title = "Storage Utilization"

          request {
            query {
              metric_query {
                name  = "used"
                query = "max:aws.rds.filesystem.used{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            query {
              metric_query {
                name  = "total"
                query = "max:aws.rds.filesystem.total{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            formula {
              formula_expression = "used"
              alias              = "Used Storage"
            }
            formula {
              formula_expression = "total"
              alias              = "Total Storage"
              style {
                palette = "grey"
              }
            }
          }
        }
      }
    }
  }

  widget {
    group_definition {
      title       = "Queries"
      layout_type = "ordered"

      # Database Queries Count (The average rate of queries)
      widget {
        timeseries_definition {
          title = "Queries"

          request {
            q = "max:aws.rds.queries{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Select Throughput (The average rate of select queries)
      widget {
        timeseries_definition {
          title = "Select Throughput"

          request {
            q = "max:aws.rds.select_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Select Latency (The average latency for select queries)
      widget {
        timeseries_definition {
          title = "Select Latency"

          request {
            q = "max:aws.rds.select_latency{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Insert Throughput (The average rate of insert queries)
      widget {
        timeseries_definition {
          title = "Insert Throughput"

          request {
            q = "max:aws.rds.insert_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Insert Latency (The average latency for insert queries)
      widget {
        timeseries_definition {
          title = "Insert Latency"

          request {
            q = "max:aws.rds.insert_latency{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Commit Throughput (The average rate of committed transactions)
      widget {
        timeseries_definition {
          title = "Commit Throughput"

          request {
            q = "max:aws.rds.commit_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Commit Latency (The amount of latency for committed transactions)
      widget {
        timeseries_definition {
          title = "Commit Latency"

          request {
            q = "max:aws.rds.commit_latency{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      dynamic "widget" {
        for_each = var.native_database_integration_enabled && var.rds_engine == "aurora-mysql" ? [1] : []
        content {
          timeseries_definition {
            title = "Slow Queries"

            request {
              q = "max:mysql.performance.slow_queries{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }
      }
    }
  }

  widget {
    group_definition {
      title       = "Connections"
      layout_type = "ordered"

      # Database Connections Line Graph (Number of database connections in use)
      widget {
        timeseries_definition {
          title = "Database Connections"

          request {
            query {
              metric_query {
                name  = "used"
                query = "max:${local.used_connections_metric}{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              }
            }
            dynamic "query" {
              for_each = var.native_database_integration_enabled && var.rds_engine == "aurora-mysql" ? [1] : []
              content {
                metric_query {
                  name  = "total"
                  query = "max:mysql.net.max_connections_available{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
                }
              }
            }
            formula {
              formula_expression = "used"
              alias              = "Used Connections"
            }
            dynamic "formula" {
              for_each = var.native_database_integration_enabled && var.rds_engine == "aurora-mysql" ? [1] : []
              content {
                formula_expression = "total"
                alias              = "Total Connections"
                style {
                  palette = "grey"
                }
              }
            }
          }
        }
      }
    }
  }

  dynamic "widget" {
    for_each = var.replication_widgets_enabled ? [1] : []
    content {
      group_definition {
        title       = "Replication"
        layout_type = "ordered"

        widget {
          timeseries_definition {
            title = "Replication Lag Min/Max"

            request {
              q = "max:aws.rds.aurora_replica_lag_maximum{environment:${var.environment},service_name:${var.service_name}}"
            }
            request {
              q = "max:aws.rds.aurora_replica_lag_minimum{environment:${var.environment},service_name:${var.service_name}}"
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Replication Lag by Instance"

            request {
              q = "max:aws.rds.aurora_replica_lag{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }
      }
    }
  }

  widget {
    group_definition {
      title       = "Disk IO"
      layout_type = "ordered"

      widget {
        timeseries_definition {
          title = "IO Latency (Reads)"

          request {
            q = "max:aws.rds.read_latency{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "IO Latency (Writes)"

          request {
            q = "max:aws.rds.write_latency{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "IO Operations (Reads)"

          request {
            q = "max:aws.rds.read_iops{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "IO Operations (Writes)"

          request {
            q = "max:aws.rds.write_iops{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "IO Throughput (Reads)"

          request {
            q = "max:aws.rds.read_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "IO Throughput (Writes)"

          request {
            q = "max:aws.rds.write_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "IO Disk Queue Depth"

          request {
            q = "max:aws.rds.disk_queue_depth{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }
    }
  }

  widget {
    group_definition {
      title       = "Network IO"
      layout_type = "ordered"

      # Database Network Receive Throughput (Incoming (Receive) network traffic on the DB instance)
      widget {
        timeseries_definition {
          title = "Network Receive Throughput"

          request {
            q = "max:aws.rds.network_receive_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }

      # Database Network Transmit Throughput (Outgoing (Transmit) network traffic on the DB instance)
      widget {
        timeseries_definition {
          title = "Network Transmit Throughput"

          request {
            q = "max:aws.rds.network_transmit_throughput{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
          }
        }
      }
    }
  }

  dynamic "widget" {
    for_each = var.native_database_integration_enabled && var.rds_engine == "aurora-mysql" ? [1] : []

    content {
      group_definition {
        title       = "MySQL Performance Metrics"
        layout_type = "ordered"

        widget {
          timeseries_definition {
            title = "InnoDB Rows Read"

            request {
              q = "max:mysql.innodb.rows_read{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }

        widget {
          timeseries_definition {
            title = "InnoDB Rows Inserted"

            request {
              q = "max:mysql.innodb.rows_inserted{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }

        widget {
          timeseries_definition {
            title = "InnoDB Rows Updated"

            request {
              q = "max:mysql.innodb.rows_updated{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }

        widget {
          timeseries_definition {
            title = "InnoDB Rows Deleted"

            request {
              q = "max:mysql.innodb.rows_deleted{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }

        widget {
          timeseries_definition {
            title = "InnoDB Buffer Pool"

            request {
              q = "max:mysql.innodb.buffer_pool_used{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
            request {
              q = "max:mysql.innodb.buffer_pool_total{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
              style {
                palette = "grey"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Table Locks"

            request {
              q = "max:mysql.performance.table_locks_immediate.rate{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
            request {
              q = "max:mysql.performance.table_locks_waited.rate{environment:${var.environment},service_name:${var.service_name},dbinstanceidentifier:$dbinstanceidentifier.value} by {dbinstanceidentifier}"
            }
          }
        }
      }
    }
  }

  tags = local.dashboard_tags
}
