data "aws_caller_identity" "current" {}

# Datadog Fargate Timeseries Dashboard
resource "datadog_dashboard" "fargate_service_timeseries_dashboard" {
  count       = var.environment_type == "fargate" && var.timeseries_dashboard_enabled ? 1 : 0
  title       = "${var.environment}-${var.service_name} timeseries dashboard"
  description = "Default terraformed timeseries dashboard for ${var.environment}-${var.service_name}"
  layout_type = "ordered"

  template_variable {
    defaults = [var.environment]
    name     = var.service_name
    prefix   = "environment"
  }

  widget {
    timeseries_definition {
      title       = "Application 2xx Requests"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.httpcode_target_2xx{service_name:${var.service_name}, environment:${var.environment}}"

      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Application 3xx Requests"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.httpcode_target_3xx{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Application 4xx Requests"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.httpcode_target_4xx{service_name:${var.service_name}, environment:${var.environment}}"

      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Application 5xx Requests"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.httpcode_target_5xx{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Total Application Requests"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.request_count{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "95th Percentile Request Time (from LB to target)"
      show_legend = true

      request {
        q = "avg:aws.applicationelb.target_response_time.p95{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "99th Percentile Request Time (from LB to target)"
      show_legend = true

      request {
        q = "avg:aws.applicationelb.target_response_time.p99{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Average Request Time (from LB to target)"
      show_legend = true

      request {
        q = "avg:aws.applicationelb.target_response_time.average{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Connection Count"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.active_connection_count{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Connection Errors"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.target_connection_error_count{service_name:${var.service_name}, environment:${var.environment}}"
      }

      request {
        q = "sum:aws.applicationelb.rejected_connection_count{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Load Balancer-Generated 4xx"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.httpcode_elb_4xx{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }


  widget {
    timeseries_definition {
      title       = "Load Balancer-Generated 5xx"
      show_legend = true

      request {
        q = "sum:aws.applicationelb.httpcode_elb_5xx{service_name:${var.service_name}, environment:${var.environment}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Running Task Count"
      show_legend = true

      request {
        q = "sum:aws.ecs.service.running{servicename:${var.environment}-${var.service_name}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "CPU Utilization"
      show_legend = true

      request {
        q = "max:aws.ecs.cpuutilization.maximum{servicename:${var.environment}-${var.service_name}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  widget {
    timeseries_definition {
      title       = "Memory Utilization"
      show_legend = true

      request {
        q = "max:aws.ecs.memory_utilization.maximum{servicename:${var.environment}-${var.service_name}}"
      }

      event {
        q = "sources:jenkins tags:result:success,deploy:${var.service_name},environment:${var.environment} priority:all"
      }
    }
  }

  tags = local.dashboard_tags
}

# Datadog Fargate Overview Screen Dashboard
resource "datadog_dashboard" "fargate_service_screen_dashboard" {
  count       = var.environment_type == "fargate" && var.screen_dashboard_enabled ? 1 : 0
  title       = "${var.environment}-${var.service_name} screen dashboard"
  layout_type = "free"

  template_variable {
    defaults = [var.environment]
    name     = var.service_name
    prefix   = "environment"
  }

  widget {
    log_stream_definition {
      live_span = "4h"
      query     = "source:${var.environment}-${var.service_name}"
      columns = [
        "source",
        "status",
      ]
      title               = "${var.environment}-${var.service_name} stdout logs"
      title_size          = 16
      title_align         = "left"
      show_date_column    = true
      show_message_column = true
    }
    widget_layout {
      width  = 100
      height = 30
      x      = 0
      y      = 0
    }
  }

  widget {
    log_stream_definition {
      live_span           = "4h"
      query               = "service:elb environment:${var.environment} service_name:${var.service_name}"
      columns             = ["status"]
      title               = "${var.environment}-${var.service_name} load balancer logs"
      title_size          = 16
      title_align         = "left"
      show_date_column    = true
      show_message_column = true
    }
    widget_layout {
      width  = 100
      height = 30
      x      = 0
      y      = 35
    }
  }

  widget {
    log_stream_definition {
      live_span           = "4h"
      query               = "source:eventbridge event:stopped_task aws_service:ecs environment:${var.environment} service_name:${var.service_name}"
      columns             = ["status"]
      title               = "${var.environment}-${var.service_name} ecs task stop reason logs"
      title_size          = 16
      title_align         = "left"
      show_date_column    = true
      show_message_column = true
    }
    widget_layout {
      width  = 100
      height = 30
      x      = 0
      y      = 70
    }
  }

  widget {
    trace_service_definition {
      live_span      = "4h"
      env            = var.environment
      service        = var.service_name
      span_name      = var.datadog_service_name
      size_format    = "large"
      display_format = "three_column"

      show_breakdown     = true
      show_distribution  = true
      show_errors        = true
      show_hits          = true
      show_latency       = true
      show_resource_list = true
      title              = "${var.datadog_service_type} #env:${var.environment} #service:${var.service_name}"
      title_size         = 16
      title_align        = "left"
    }
    widget_layout {
      width  = 100
      height = 36
      x      = 0
      y      = 110
    }
  }

  tags = local.dashboard_tags
}

resource "datadog_monitor" "healthy_tasks_monitor" {
  count = var.healthy_tasks_monitor_enabled ? 1 : 0
  name  = "${var.environment}-${var.service_name} healthy tasks monitor"
  type  = "metric alert"
  message = templatefile("${path.module}/templates/notifications.tftpl", {
    notification_endpoints         = coalesce(var.healthy_tasks_notification_overrides, local.default_notification_settings).endpoints
    alert_notification_endpoints   = coalesce(var.healthy_tasks_notification_overrides, local.default_notification_settings).alert_endpoints
    no_data_notification_endpoints = coalesce(var.healthy_tasks_notification_overrides, local.default_notification_settings).no_data_endpoints
  })
  escalation_message = "Escalation to ${coalesce(var.healthy_tasks_notification_overrides, local.default_notification_settings).escalation_endpoints}"

  query = "avg(${var.healthy_tasks_evaluation_window}):avg:${local.healthy_tasks_monitor_metric[var.environment_type]}{${local.healthy_tasks_filter[var.environment_type]}} < ${var.healthy_tasks_critical_number}"

  monitor_thresholds {
    ok                = var.healthy_tasks_ok_number
    warning           = var.healthy_tasks_warning_number
    warning_recovery  = var.healthy_tasks_warning_recovery_number
    critical          = var.healthy_tasks_critical_number
    critical_recovery = var.healthy_tasks_critical_recovery_number
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  renotify_interval   = 60
  timeout_h           = 0
  require_full_window = false
  no_data_timeframe   = 0

  tags = local.combined_resource_tags
}

resource "datadog_monitor" "service_cpu_monitor" {
  count = var.service_cpu_monitor_enabled ? 1 : 0
  name  = "${var.environment}-${var.service_name} cpu monitor"
  type  = "metric alert"
  message = templatefile("${path.module}/templates/notifications.tftpl", {
    notification_endpoints         = coalesce(var.service_cpu_notification_overrides, local.default_notification_settings).endpoints
    alert_notification_endpoints   = coalesce(var.service_cpu_notification_overrides, local.default_notification_settings).alert_endpoints
    no_data_notification_endpoints = coalesce(var.service_cpu_notification_overrides, local.default_notification_settings).no_data_endpoints
  })
  escalation_message = "Escalation to ${coalesce(var.service_cpu_notification_overrides, local.default_notification_settings).escalation_endpoints}"

  query = "${var.service_cpu_monitor_evaluation_function}(${var.service_cpu_time_window}):avg:${local.service_cpu_monitor_metric[var.environment_type]}{${local.service_cpu_monitor_filter[var.environment_type]}} > ${var.service_cpu_critical_number}"

  monitor_thresholds {
    ok                = var.service_cpu_ok_number
    warning           = var.service_cpu_warning_number
    warning_recovery  = var.service_cpu_warning_recovery_number
    critical          = var.service_cpu_critical_number
    critical_recovery = var.service_cpu_critical_recovery_number
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  renotify_interval   = 60
  timeout_h           = 0
  require_full_window = false
  no_data_timeframe   = 0

  tags = local.combined_resource_tags
}

resource "datadog_monitor" "service_4xx_monitor" {
  count = var.service_4xx_monitor_enabled ? 1 : 0
  name  = "${var.environment}-${var.service_name} 4xx requests monitor"
  type  = "metric alert"
  message = templatefile("${path.module}/templates/notifications.tftpl", {
    notification_endpoints         = coalesce(var.notification_overrides_4xx, local.default_notification_settings).endpoints
    alert_notification_endpoints   = coalesce(var.notification_overrides_4xx, local.default_notification_settings).alert_endpoints
    no_data_notification_endpoints = coalesce(var.notification_overrides_4xx, local.default_notification_settings).no_data_endpoints
  })
  escalation_message = "Escalation to ${coalesce(var.notification_overrides_4xx, local.default_notification_settings).escalation_endpoints}"

  query = "sum(last_5m):sum:${local.service_4xx_monitor_metric[var.environment_type]}{service_name:${var.service_name}, environment:${var.environment}} > ${var.critical_number_4xx}"

  monitor_thresholds {
    ok                = var.ok_number_4xx
    warning           = var.warning_number_4xx
    warning_recovery  = var.warning_recovery_number_4xx
    critical          = var.critical_number_4xx
    critical_recovery = var.critical_recovery_number_4xx
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  renotify_interval   = 60
  timeout_h           = 0
  require_full_window = false
  no_data_timeframe   = 0

  tags = local.combined_resource_tags
}

resource "datadog_monitor" "service_5xx_monitor" {
  count = var.service_5xx_monitor_enabled ? 1 : 0
  name  = "${var.environment}-${var.service_name} 5xx requests monitor"
  type  = "metric alert"
  message = templatefile("${path.module}/templates/notifications.tftpl", {
    notification_endpoints         = coalesce(var.notification_overrides_5xx, local.default_notification_settings).endpoints
    alert_notification_endpoints   = coalesce(var.notification_overrides_5xx, local.default_notification_settings).alert_endpoints
    no_data_notification_endpoints = coalesce(var.notification_overrides_5xx, local.default_notification_settings).no_data_endpoints
  })
  escalation_message = "Escalation to ${coalesce(var.notification_overrides_5xx, local.default_notification_settings).escalation_endpoints}"

  query = "sum(last_5m):sum:${local.service_5xx_monitor_metric[var.environment_type]}{service_name:${var.service_name}, environment:${var.environment}}.as_count() + sum:${local.service_alb_5xx_monitor_metric[var.environment_type]}{service_name:${var.service_name}, environment:${var.environment}}.as_count() > ${var.critical_number_5xx}"

  monitor_thresholds {
    ok                = var.ok_number_5xx
    warning           = var.warning_number_5xx
    warning_recovery  = var.warning_recovery_number_5xx
    critical          = var.critical_number_5xx
    critical_recovery = var.critical_recovery_number_5xx
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  renotify_interval   = 60
  timeout_h           = 0
  require_full_window = false
  no_data_timeframe   = 0

  tags = local.combined_resource_tags
}

resource "datadog_monitor" "failed_tasks_monitor" {
  count = var.failed_tasks_monitor_enabled ? 1 : 0
  name  = "${var.environment}-${var.service_name} failed tasks monitor"
  type  = "metric alert"
  message = templatefile("${path.module}/templates/notifications.tftpl", {
    notification_endpoints         = coalesce(var.notification_overrides_failed_tasks, local.default_notification_settings).endpoints
    alert_notification_endpoints   = coalesce(var.notification_overrides_failed_tasks, local.default_notification_settings).alert_endpoints
    no_data_notification_endpoints = coalesce(var.notification_overrides_failed_tasks, local.default_notification_settings).no_data_endpoints
  })
  escalation_message = "Escalation to ${coalesce(var.notification_overrides_failed_tasks, local.default_notification_settings).escalation_endpoints}"

  query = "sum(last_5m):sum:ecs.failed_tasks{service_name:${var.service_name}, environment:${var.environment}} >= ${var.critical_number_failed_tasks}"

  monitor_thresholds {
    warning           = var.warning_number_failed_tasks
    warning_recovery  = var.warning_recovery_number_failed_tasks
    critical          = var.critical_number_failed_tasks
    critical_recovery = var.critical_recovery_number_failed_tasks
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  renotify_interval   = 60
  timeout_h           = 0
  require_full_window = false
  no_data_timeframe   = 0

  tags = local.combined_resource_tags
}

resource "datadog_monitor" "successful_tasks_monitor" {
  count = var.successful_tasks_monitor_enabled ? 1 : 0
  name  = "${var.environment}-${var.service_name} successful tasks monitor"
  type  = "metric alert"
  message = templatefile("${path.module}/templates/notifications.tftpl", {
    notification_endpoints         = coalesce(var.notification_overrides_successful_tasks, local.default_notification_settings).endpoints
    alert_notification_endpoints   = coalesce(var.notification_overrides_successful_tasks, local.default_notification_settings).alert_endpoints
    no_data_notification_endpoints = coalesce(var.notification_overrides_successful_tasks, local.default_notification_settings).no_data_endpoints
  })
  escalation_message = "Escalation to ${coalesce(var.notification_overrides_successful_tasks, local.default_notification_settings).escalation_endpoints}"

  query = "sum(${var.successful_tasks_query_interval}):sum:ecs.successful_tasks{service_name:${var.service_name}, environment:${var.environment}}${var.successful_tasks_group_by == null ? "" : " by {${var.successful_tasks_group_by}}"} < ${var.critical_number_successful_tasks}"

  monitor_thresholds {
    warning           = var.warning_number_successful_tasks
    warning_recovery  = var.warning_recovery_number_successful_tasks
    critical          = var.critical_number_successful_tasks
    critical_recovery = var.critical_recovery_number_successful_tasks
  }

  include_tags        = true
  notify_no_data      = true
  notify_audit        = false
  renotify_interval   = 60
  timeout_h           = 0
  require_full_window = false
  no_data_timeframe   = 0

  tags = local.combined_resource_tags
}

resource "datadog_downtime_schedule" "healthy_tasks_monitor_downtime" {
  count = var.healthy_tasks_monitor_silenced ? 1 : 0
  scope = "*"
  monitor_identifier {
    monitor_id = datadog_monitor.healthy_tasks_monitor[count.index].id
  }

  recurring_schedule {
    recurrence {
      duration = "24h"
      rrule    = "FREQ=DAILY;INTERVAL=1"
    }
  }
}

resource "datadog_downtime_schedule" "service_cpu_monitor_downtime" {
  count = var.service_cpu_monitor_silenced ? 1 : 0
  scope = "*"
  monitor_identifier {
    monitor_id = datadog_monitor.service_cpu_monitor[count.index].id
  }

  recurring_schedule {
    recurrence {
      duration = "24h"
      rrule    = "FREQ=DAILY;INTERVAL=1"
    }
  }
}

resource "datadog_downtime_schedule" "service_4xx_monitor_downtime" {
  count = var.service_4xx_monitor_silenced ? 1 : 0
  scope = "*"
  monitor_identifier {
    monitor_id = datadog_monitor.service_4xx_monitor[count.index].id
  }

  recurring_schedule {
    recurrence {
      duration = "24h"
      rrule    = "FREQ=DAILY;INTERVAL=1"
    }
  }
}

resource "datadog_downtime_schedule" "service_5xx_monitor_downtime" {
  count = var.service_5xx_monitor_silenced ? 1 : 0
  scope = "*"
  monitor_identifier {
    monitor_id = datadog_monitor.service_5xx_monitor[count.index].id
  }

  recurring_schedule {
    recurrence {
      duration = "24h"
      rrule    = "FREQ=DAILY;INTERVAL=1"
    }
  }
}
