resource "datadog_dashboard" "main" {
  count = var.dashboard_configuration.enabled ? 1 : 0

  title       = "${var.environment}-${var.service_name} S3 timeboard"
  description = "Default terraformed timeboard for S3"
  layout_type = "ordered"

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

      widget {
        timeseries_definition {
          title = "Number of Objects"

          request {
            q = "sum:aws.s3.number_of_objects{bucketname:${local.bucket_name}}.rollup(max, daily)"
            metadata {
              expression = "sum:aws.s3.number_of_objects{bucketname:${local.bucket_name}}.rollup(max, daily)"
              alias_name = "Number of Objects"
            }
          }
        }
      }

      widget {
        timeseries_definition {
          title         = "Bucket Size"
          show_legend   = true
          legend_layout = "horizontal"

          request {
            q            = "sum:aws.s3.bucket_size_bytes{bucketname:${local.bucket_name}} by {storagetype}.rollup(max, daily)"
            display_type = "area"
            metadata {
              expression = "sum:aws.s3.bucket_size_bytes{bucketname:${local.bucket_name}} by {storagetype}.rollup(max, daily)"
              alias_name = "Bucket Size"
            }
          }
        }
      }
    }
  }

  dynamic "widget" {
    for_each = var.dashboard_configuration.show_advanced_storage_metrics ? [true] : []

    content {
      group_definition {
        title       = "Advanced Storage Metrics"
        layout_type = "ordered"

        widget {
          timeseries_definition {
            title         = "Number of Objects by Object Type"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q = "sum:aws.s3.storagelens.current_version_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.current_version_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Current Versions"
              }
            }

            request {
              q = "sum:aws.s3.storagelens.non_current_version_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.non_current_version_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Non Current Versions"
              }
            }

            request {
              q = "sum:aws.s3.storagelens.incomplete_multipart_upload_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.incomplete_multipart_upload_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Incomplete Multipart Uploads"
              }
            }

            request {
              q = "sum:aws.s3.storagelens.delete_marker_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.delete_marker_object_count{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Delete Markers"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Storage by Object Type"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q = "sum:aws.s3.storagelens.current_version_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.current_version_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Current Versions"
              }
            }

            request {
              q = "sum:aws.s3.storagelens.non_current_version_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.non_current_version_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Non Current Versions"
              }
            }

            request {
              q = "sum:aws.s3.storagelens.incomplete_multipart_upload_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.incomplete_multipart_upload_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Incomplete Multipart Uploads"
              }
            }

            request {
              q = "sum:aws.s3.storagelens.delete_marker_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.storagelens.delete_marker_storage_bytes{bucket_name:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Delete Markers"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Current Objects"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.current_version_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.current_version_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Object Count"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Current Object Storage"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.current_version_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.current_version_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Storage Used"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Non Current Objects"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.non_current_version_object_count{bucket_name:${local.bucket_name}}by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.non_current_version_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Object Count"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Non Current Object Storage"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.non_current_version_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.non_current_version_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Storage Used"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Incomplete Multipart Upload Objects"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.incomplete_multipart_upload_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.incomplete_multipart_upload_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Object Count"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Incomplete Multipart Upload Storage"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.incomplete_multipart_upload_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.incomplete_multipart_upload_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Storage Used"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Delete Marker Objects"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.delete_marker_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.delete_marker_object_count{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Object Count"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Delete Marker Storage"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.delete_marker_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.delete_marker_storage_bytes{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Storage Used"
              }
            }
          }
        }
      }
    }
  }

  dynamic "widget" {
    for_each = var.dashboard_configuration.show_replication_metrics ? [true] : []

    content {
      group_definition {
        title       = "Replication"
        layout_type = "ordered"

        widget {
          timeseries_definition {
            title = "Replication Latency"

            request {
              q = "max:aws.s3.replication_latency{sourcebucket:${local.bucket_name}} by {ruleid}"
              metadata {
                expression = "max:aws.s3.replication_latency{sourcebucket:${local.bucket_name}} by {ruleid}"
                alias_name = "Replication Latency"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Replication Failures"

            request {
              q = "max:aws.s3.operations_failed_replication.sum{sourcebucket:${local.bucket_name}} by {ruleid}"
              metadata {
                expression = "max:aws.s3.operations_failed_replication.sum{sourcebucket:${local.bucket_name}} by {ruleid}"
                alias_name = "Replication Failures"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Operations Pending Replication"

            request {
              q = "sum:aws.s3.operations_pending_replication{sourcebucket:${local.bucket_name}} by {ruleid}"
              metadata {
                expression = "sum:aws.s3.operations_pending_replication{sourcebucket:${local.bucket_name}} by {ruleid}"
                alias_name = "Operations Pending Replication"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Bytes Pending Replication"

            request {
              q = "sum:aws.s3.bytes_pending_replication{sourcebucket:${local.bucket_name}} by {ruleid}"
              metadata {
                expression = "sum:aws.s3.bytes_pending_replication{sourcebucket:${local.bucket_name}} by {ruleid}"
                alias_name = "Bytes Pending Replication"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Replicated Object Count"

            request {
              q            = "sum:aws.s3.storagelens.replicated_object_count_source{bucket_name:${local.bucket_name}} by {configuration_id}.rollup(max, daily) "
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.replicated_object_count_source{bucket_name:${local.bucket_name}} by {configuration_id}.rollup(max, daily) "
                alias_name = "Replicated Object Count"
              }
            }
            request {
              q = "sum:aws.s3.number_of_objects{bucketname:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.number_of_objects{bucketname:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Total Objects"
              }
              style {
                palette    = "green"
                line_type  = "dashed"
                line_width = "thin"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title = "Replicated Object Storage"

            request {
              q            = "sum:aws.s3.storagelens.replicated_storage_bytes_source{bucket_name:${local.bucket_name}} by {configuration_id}.rollup(max, daily)"
              display_type = "area"
              metadata {
                expression = "sum:aws.s3.storagelens.replicated_storage_bytes_source{bucket_name:${local.bucket_name}} by {configuration_id}.rollup(max, daily)"
                alias_name = "Replicated Storage"
              }
            }
            request {
              q = "sum:aws.s3.bucket_size_bytes{bucketname:${local.bucket_name}}.rollup(max, daily)"
              metadata {
                expression = "sum:aws.s3.bucket_size_bytes{bucketname:${local.bucket_name}}.rollup(max, daily)"
                alias_name = "Total Storage"
              }
              style {
                palette    = "green"
                line_type  = "dashed"
                line_width = "thin"
              }
            }
          }
        }

        widget {
          list_stream_definition {
            title = "Replication Failure Events"

            request {
              response_format = "event_list"

              # Provider forces us to specify columns here, even though it doesn't do anything for event lists
              columns {
                field = ""
                width = "auto"
              }

              query {
                data_source  = "event_stream"
                event_size   = "l"
                query_string = "source:amazon_s3 bucket_name:${local.bucket_name} replication_rule_id:*"
              }
            }
          }
        }
      }
    }
  }

  dynamic "widget" {
    for_each = var.dashboard_configuration.show_activity_metrics ? [true] : []

    content {
      group_definition {
        title       = "Activity"
        layout_type = "ordered"

        widget {
          timeseries_definition {
            title         = "All Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.all_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.all_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "All Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Get Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.get_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.get_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Get Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Put Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.put_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.put_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Put Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Head Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.head_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.head_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Head Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Post Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.post_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.post_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Post Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Delete Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.delete_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.delete_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Delete Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "List Requests"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.list_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.list_requests{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "List Requests"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Bytes Downloaded"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.bytes_downloaded{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.bytes_downloaded{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Bytes Downloaded"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "Bytes Uploaded"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.bytes_uploaded{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.bytes_uploaded{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "Bytes Uploaded"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "4xx Errors"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.4xx_errors{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.4xx_errors{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "4xx Errors"
              }
            }
          }
        }

        widget {
          timeseries_definition {
            title         = "5xx Errors"
            show_legend   = true
            legend_layout = "horizontal"

            request {
              q            = "sum:aws.s3.storagelens.5xx_errors{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
              display_type = "bars"
              metadata {
                expression = "sum:aws.s3.storagelens.5xx_errors{bucket_name:${local.bucket_name}} by {storage_class}.rollup(max, daily)"
                alias_name = "5xx Errors"
              }
            }
          }
        }
      }
    }
  }

  tags = local.dashboard_tags
}
