
resource "datadog_dashboard" "datadog_statemachine" {
  title       = "${var.environment}-${var.service_name} dashboard"
  description = "SFN State Machine + Lambdas dashboard"
  layout_type = "free"

  # Widgets defined in variables.tf locals

  # Titles
  dynamic "widget" {
    for_each = local.title_notes

    content {
      widget_layout {
        x      = widget.value["pos_x"]
        y      = widget.value["pos_y"]
        width  = widget.value["width"]
        height = widget.value["height"]
      }
      note_definition {
        content          = widget.value["content"]
        background_color = "gray"
        font_size        = 18
        text_align       = "center"
        show_tick        = true
        tick_pos         = "50%"
        tick_edge        = "bottom"
      }
    }
  }

  # Timeseries barcharts
  dynamic "widget" {
    for_each = local.timeseries_bars_definitions

    content {
      widget_layout {
        x      = widget.value["pos_x"]
        y      = widget.value["pos_y"]
        width  = widget.value["width"]
        height = widget.value["height"]
      }

      timeseries_definition {
        title       = widget.value["title"]
        title_size  = 16
        title_align = "left"
        show_legend = true

        request {
          display_type = "bars"

          dynamic "query" {
            for_each = widget.value["queries"]

            content {
              metric_query {
                data_source = "metrics"
                name        = query.value["name"]
                query       = query.value["query"]
              }
            }
          }
          dynamic "formula" {
            for_each = widget.value["queries"]

            content {
              style {
                palette       = formula.value["palette_color"]
                palette_index = formula.value["palette_index"]
              }
              alias              = formula.value["alias"]
              formula_expression = formula.value["name"]
            }
          }
        }
      }
    }
  }

  # Timeseries line charts
  dynamic "widget" {
    for_each = local.timeseries_lines_definitions

    content {
      widget_layout {
        x      = widget.value["pos_x"]
        y      = widget.value["pos_y"]
        height = widget.value["height"]
        width  = widget.value["width"]
      }
      timeseries_definition {
        title       = widget.value["title"]
        title_size  = 16
        title_align = "left"
        show_legend = true

        request {
          display_type = "line"

          style {
            line_type  = widget.value["line_type"]
            line_width = widget.value["line_width"]
            palette    = widget.value["palette"]
          }

          dynamic "query" {
            for_each = widget.value["queries"]

            content {
              metric_query {
                data_source = "metrics"
                name        = query.value["name"]
                query       = query.value["query"]
              }
            }
          }
        }
      }
    }
  }

  # Timeseries area charts
  dynamic "widget" {
    for_each = local.timeseries_area_definitions

    content {
      widget_layout {
        x      = widget.value["pos_x"]
        y      = widget.value["pos_y"]
        height = widget.value["height"]
        width  = widget.value["width"]
      }
      timeseries_definition {
        title       = widget.value["title"]
        title_size  = 16
        title_align = "left"
        show_legend = true

        request {
          display_type = "area"

          style {
            line_type  = widget.value["line_type"]
            line_width = widget.value["line_width"]
            palette    = widget.value["palette"]
          }

          dynamic "query" {
            for_each = widget.value["queries"]

            content {
              metric_query {
                data_source = "metrics"
                name        = query.value["name"]
                query       = query.value["query"]
              }
            }
          }
        }
      }
    }
  }

  # Query Value widgets
  dynamic "widget" {
    for_each = local.query_value_definitions

    content {
      widget_layout {
        x      = widget.value["pos_x"]
        y      = widget.value["pos_y"]
        height = widget.value["height"]
        width  = widget.value["width"]
      }
      query_value_definition {
        title       = widget.value["title"]
        title_size  = 16
        title_align = "left"
        autoscale   = true
        precision   = 2

        request {
          query {
            metric_query {
              data_source = "metrics"
              name        = widget.value["name"]
              query       = widget.value["query"]
              aggregator  = widget.value["aggregator"]
            }
          }
          dynamic "conditional_formats" {
            for_each = widget.value["conditional_formats"]

            content {
              comparator = conditional_formats.value["comparator"]
              value      = conditional_formats.value["value"]
              palette    = conditional_formats.value["palette"]
            }
          }
        }
      }
    }
  }


  # TopList widgets
  dynamic "widget" {
    for_each = local.toplist_definitions

    content {
      widget_layout {
        x      = widget.value["pos_x"]
        y      = widget.value["pos_y"]
        height = widget.value["height"]
        width  = widget.value["width"]
      }

      toplist_definition {
        title       = widget.value["title"]
        title_size  = 16
        title_align = "left"

        request {
          style {
            palette = widget.value["palette_style"]
          }

          dynamic "query" {
            for_each = widget.value["queries"]

            content {
              metric_query {
                data_source = "metrics"
                name        = query.value["name"]
                query       = query.value["query"]
                aggregator  = query.value["aggregator"]
              }
            }
          }
          formula {
            formula_expression = widget.value["formula"]
            limit {
              count = widget.value["limit_count"]
              order = widget.value["order"]
            }
          }
        }
      }
    }
  }

  tags = local.dashboard_tags
}

# Log monitor for StateMachine ExecutionFailed with error message
# based of StateMachine logging ERRORs in CloudWatch
resource "datadog_monitor" "statemachine_failed_log_monitor" {
  count              = var.failed_execution_message_log_monitor.enabled ? 1 : 0
  name               = "${var.environment}-${var.service_name} failed log monitor on {{log.attributes.host}}"
  type               = "log alert"
  message            = "{{#is_alert}}\nState Machine ExecutionFailed with cause:\n\n```\n{{{log.attributes.[details.cause]}}}\n```\n\n\nNotify: ${var.notification_endpoints} \n{{/is_alert}}"
  escalation_message = "Escalation to ${var.escalation_notification_endpoints}"

  query = "logs(\"source:cloudwatch @aws.awslogs.logGroup:${var.failed_execution_message_log_monitor.log_group_name}* @type:ExecutionFailed\").index(\"*\").rollup(\"count\").last(\"1m\") >= 1"

  monitor_thresholds {
    critical = 1
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  timeout_h           = 0
  require_full_window = false
  tags                = local.tags
}


# Metric monitor for StateMachine failures
resource "datadog_monitor" "statemachine_failed_metric_monitor" {
  count              = var.failed_execution_metric_monitor_enabled ? 1 : 0
  name               = "${var.environment}-${var.service_name} execution failed monitor"
  type               = "metric alert"
  message            = "{{#is_alert}} Monitor triggered. Notify: ${var.notification_endpoints} {{/is_alert}}"
  escalation_message = "Escalation to ${var.escalation_notification_endpoints}"

  query = "sum(last_${var.statemachine_failed_metric_monitor_window}m):default(sum:aws.states.executions_failed{statemachinearn:${local.arn_lower}}.as_count() + sum:aws.states.executions_timed_out{statemachinearn:${local.arn_lower}}.as_count(), 0) >= 1"

  monitor_thresholds {
    critical = 1
  }

  include_tags        = true
  notify_no_data      = false
  notify_audit        = false
  timeout_h           = 0
  require_full_window = false
  evaluation_delay    = 900
  tags                = local.tags
}
