# General variables
variable "environment" {
  description = "Name of the environment, e.g. dev, qa, prod"
  default     = "dev"
}

variable "service_name" {
  description = "Service name, without environment prefix"
  default     = "statemachine-name"
}

variable "application_family" {
  description = "Application family to which this service belongs"
}

variable "teams" {
  type        = set(string)
  description = "A set of Datadog Teams to associate the resources with"
  default     = []
}

# AWS variables
variable "aws_region" {
  description = "AWS region from which to pull metrics"
  default     = "us-east-1"
}

# Optional Monitor Alerts
variable "notification_endpoints" {
  description = "Endpoints for alerts. Can be email, slack, pagerduty, etc"
  default     = "@slack-monitoring"
}

variable "escalation_notification_endpoints" {
  description = "Endpoints for escalation alerts. Can be email, slack, pagerduty, etc"
  default     = "@slack-monitoring"
}

variable "failed_execution_metric_monitor_enabled" {
  description = "Enable metric monitor on StateMachine failed executions."
  default     = false
}

# Enable log based monitor that provides error message in notification
# This requires StepFunction Cloudwatch logs to be enabled and shipped to DataDog
variable "failed_execution_message_log_monitor" {
  type = object({
    enabled        = bool
    log_group_name = string
  })
  default = {
    enabled        = false
    log_group_name = ""
  }

  validation {
    condition     = var.failed_execution_message_log_monitor.enabled == false || length(var.failed_execution_message_log_monitor.log_group_name) > 1
    error_message = "Please provide a valid failed_execution_message_log_monitor.log_group_name or set enabled to false."
  }
}

# SFN
variable "statemachine_arn" {
  description = "State Machine ARN"
}

variable "statemachine_failed_metric_monitor_window" {
  description = "Window in minutes for the state machine failure metric monitor"
  default     = 1
}


locals {
  # ARN needs to be all lowercase
  arn_lower = lower(var.statemachine_arn)

  # Widgets

  title_notes = [
    {
      content = "State Machine executions"
      pos_x   = 0
      pos_y   = 0
      width   = 47
      height  = 6
    },
    {
      content = "State Machine execution times"
      pos_x   = 49
      pos_y   = 0
      width   = 47
      height  = 6
    },
    {
      content = "Lambda state executions"
      pos_x   = 98
      pos_y   = 0
      width   = 47
      height  = 6
    },
    {
      content = "Failed and slowest lambda steps"
      pos_x   = 147
      pos_y   = 0
      width   = 47
      height  = 6
    }
  ]

  timeseries_bars_definitions = [
    {
      title  = "State Executions"
      pos_x  = 0
      pos_y  = 7
      height = 15
      width  = 47
      queries = [
        {
          name          = "succeeded_query"
          query         = "sum:aws.states.executions_succeeded{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Succeeded"
          palette_color = "green"
          palette_index = 3
        },
        {
          name          = "failed_query"
          query         = "sum:aws.states.executions_failed{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Failed"
          palette_color = "warm"
          palette_index = 5
        }
      ]
    },
    {
      title  = "All execution issues"
      pos_x  = 0
      pos_y  = 42
      height = 15
      width  = 47
      queries = [
        {
          name          = "aborted_query"
          query         = "sum:aws.states.executions_aborted{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Aborted"
          palette_color = "gray"
          palette_index = 2
        },
        {
          name          = "failed_query"
          query         = "sum:aws.states.executions_failed{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Failed"
          palette_color = "warm"
          palette_index = 5
        },
        {
          name          = "throttled_query"
          query         = "sum:aws.states.executions_throttled{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Failed"
          palette_color = "orange"
          palette_index = 4
        },
        {
          name          = "timedout_query"
          query         = "sum:aws.states.executions_timed_out{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Timed out"
          palette_color = "orange"
          palette_index = 7
        }
      ]
    },
    {
      title  = "Lambda state executions"
      pos_x  = 98
      pos_y  = 24
      height = 15
      width  = 47
      queries = [
        {
          name          = "succeeded_query"
          query         = "sum:aws.states.lambda_functions_succeeded{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Succeeded"
          palette_color = "green"
          palette_index = 3
        },
        {
          name          = "failed_query"
          query         = "sum:aws.states.lambda_functions_failed{statemachinearn:${local.arn_lower}}.as_count()"
          alias         = "Failed"
          palette_color = "warm"
          palette_index = 5
        }
      ]
    }
  ]

  timeseries_lines_definitions = [
    {
      title      = "p95 execution time"
      pos_x      = 49
      pos_y      = 24
      height     = 15
      width      = 47
      palette    = "dog_classic"
      line_width = "normal"
      line_type  = "solid"
      queries = [
        {
          name  = "p95_time"
          query = "avg:aws.states.execution_time.p95{statemachinearn:${local.arn_lower}}"
        }
      ]
    },
  ]

  timeseries_area_definitions = [
    {
      title      = "p95 run time by step"
      pos_x      = 98
      pos_y      = 42
      height     = 15
      width      = 47
      palette    = "dog_classic"
      line_width = "normal"
      line_type  = "solid"
      queries = [
        {
          name  = "p95_time"
          query = "avg:aws.states.lambda_function_time.p95{statemachinearn:${local.arn_lower}} by {stepname}"

        }
      ]
    },
  ]

  query_value_definitions = [
    {
      # SFN Aborted
      title      = "Aborted"
      name       = "executions_aborted"
      query      = "sum:aws.states.execution_aborted{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 0
      pos_y      = 24
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">="
          value      = 0
          palette    = "white_on_gray"
        }
      ]
    },
    {
      # SFN Throttled
      title      = "Throttled"
      name       = "execution_throttled"
      query      = "sum:aws.states.execution_throttled{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 12
      pos_y      = 24
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_red"
        },
        {
          comparator = "<"
          value      = 1
          palette    = "white_on_green"
        }
      ]
    },
    {
      # SFN Timed out
      title      = "Timed out"
      name       = "executions_timed_out"
      query      = "sum:aws.states.executions_timed_out{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 24
      pos_y      = 24
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_red"
        },
        {
          comparator = "<"
          value      = 1
          palette    = "white_on_green"
        }
      ]
    },
    {
      # SFN Failed
      title      = "Failed"
      name       = "executions_failed"
      query      = "sum:aws.states.executions_failed{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 36
      pos_y      = 24
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_red"
        },
        {
          comparator = "<"
          value      = 1
          palette    = "white_on_green"
        }
      ]
    },
    {
      # SFN Slowest execution
      title      = "Slowest"
      name       = "slowest_execution"
      query      = "max:aws.states.execution_time.maximum{statemachinearn:${local.arn_lower}}"
      aggregator = "max"
      pos_x      = 49
      pos_y      = 7
      height     = 15
      width      = 15
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_red"
        }
      ]
    },
    {
      # SFN Fastest execution
      title      = "Fastest"
      name       = "fastest_execution"
      query      = "min:aws.states.execution_time.minimum{statemachinearn:${local.arn_lower}}"
      aggregator = "min"
      pos_x      = 65
      pos_y      = 7
      height     = 15
      width      = 15
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_green"
        }
      ]
    },
    {
      # SFN Avg execution
      title      = "Average"
      name       = "average_execution"
      query      = "avg:aws.states.execution_time{statemachinearn:${local.arn_lower}}"
      aggregator = "avg"
      pos_x      = 81
      pos_y      = 7
      height     = 15
      width      = 15
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_gray"
        }
      ]
    },
    {
      # Lambda Succeeded
      title      = "Succeeded"
      name       = "lambdas_succeeded"
      query      = "sum:aws.states.lambda_functions_succeeded{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 98
      pos_y      = 7
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_green"
        },
        {
          comparator = "<"
          value      = 1
          palette    = "white_on_gray"
        }
      ]
    },
    {
      # Lambda Started
      title      = "Started"
      name       = "lambdas_started"
      query      = "sum:aws.states.lambda_functions_started{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 110
      pos_y      = 7
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_gray"
        }
      ]
    },
    {
      # Lambda Failed
      title      = "Failed"
      name       = "lambdas_failed"
      query      = "sum:aws.states.lambda_functions_failed{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 122
      pos_y      = 7
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_red"
        },
        {
          comparator = "<"
          value      = 1
          palette    = "white_on_green"
        }
      ]
    },
    {
      # Lambda Timed out
      title      = "Timed out"
      name       = "lambdas_timed_out"
      query      = "sum:aws.states.lambda_functions_timed_out{statemachinearn:${local.arn_lower}}.as_count()"
      aggregator = "sum"
      pos_x      = 134
      pos_y      = 7
      height     = 15
      width      = 11
      conditional_formats = [
        {
          comparator = ">"
          value      = 0
          palette    = "white_on_red"
        },
        {
          comparator = "<"
          value      = 1
          palette    = "white_on_green"
        }
      ]
    },
  ]

  toplist_definitions = [
    {
      title         = "Top Lambda step failures"
      palette_style = "dog_classic"
      pos_x         = 147
      pos_y         = 7
      height        = 24
      width         = 47
      queries = [
        {
          name       = "failed_functions"
          query      = "sum:aws.states.lambda_functions_failed{statemachinearn:${local.arn_lower}} by {lambdafunctionarn}.as_count()"
          aggregator = "sum"
        },
        {
          name       = "timedout_functions"
          query      = "sum:aws.states.lambda_functions_timed_out{statemachinearn:${local.arn_lower}} by {lambdafunctionarn}.as_count()"
          aggregator = "sum"
        }
      ],
      formula     = "failed_functions + timedout_functions"
      limit_count = 10
      order       = "desc"
    },
    {
      title         = "Slowest steps (p95 run time)"
      palette_style = "dog_classic"
      pos_x         = 147
      pos_y         = 33
      height        = 24
      width         = 47
      queries = [
        {
          name       = "lambda_function_times"
          query      = "avg:aws.states.lambda_function_time.p95{statemachinearn:${local.arn_lower}} by {stepname}"
          aggregator = "avg"
        }
      ],
      formula     = "lambda_function_times"
      limit_count = 10
      order       = "desc"
    }
  ]

  # Only team tags are supported for dashboards
  dashboard_tags = [for team in var.teams : "team:${team}"]

  tags = flatten([
    "application_family:${var.application_family}",
    "env:${var.environment}",
    "environment:${var.environment}",
    "service:${var.service_name}",
    "service_name:${var.service_name}",
    [for team in var.teams : "team:${team}"],
  ])
}
