terraform {
  backend "s3" {
    bucket                  = "dev-dna-tfstate"
    key                     = "gdb/delphi/qa/lambda-daily-data-alert/terraform.tfstate"
    region                  = "us-east-1"
    shared_credentials_file = "~/.aws/credentials"
    profile                 = "gdb-delphi-dev"
    dynamodb_table          = "terraform-state-lock-dynamodb"
  }
}

module "default_tags" {
  source             = "git@github.com:theorchard/terraform-default-tags.git//?ref=1.0.0"
  environment        = var.environment
  application_family = var.application_family
  service_name       = var.service_name
}

provider "aws" {
  region  = var.aws_region
  profile = var.aws_profile

  default_tags {
    tags = module.default_tags.tags
  }
}

data "aws_caller_identity" "current" {}

module "lambda" {
  source = "git@github.com:theorchard/terraform-lambda.git?ref=3.1.0"

  environment                = var.environment
  application_family         = var.application_family
  lambda_name                = var.service_name
  lambda_description         = "Generates datadog metrics and sends daily alert"
  use_container_image        = true
  container_image_custom_uri = "${data.aws_ecr_repository.lambda.repository_url}:develop" # Tag will be updated during the deployment
  lambda_function_timeout    = "900"
  splitio_enabled            = false

  vpc_enabled             = true
  vpc_id                  = data.aws_vpc.main.id
  vpc_subnet_ids          = data.aws_subnets.private.ids
  vpc_security_group_name = data.aws_security_group.lambda.name

  datadog_advanced_enabled            = true
  datadog_advanced_api_key_secret_arn = data.aws_secretsmanager_secret.dd_api_key.arn

  dlq_enabled                    = false
  ows_machine_to_machine_enabled = false

  cloudwatch_event_enabled = true
  cloudwatch_event_rules = [
    {
      name     = "${var.service_name}-ae-event"
      schedule = "rate(1 hour)"
      input    = jsonencode({ "dsp" = "appreciation_engine" })
    },
    {
      name     = "${var.service_name}-spotify-event"
      schedule = "rate(1 hour)"
      input    = jsonencode({ "dsp" = "spotify" })
    },
  ]

  iam_managed_policy_attachments = [
    for k, v in data.aws_iam_policy.policies : v.arn
  ]
  lambda_function_reserved_concurrent_executions = "100"
  lambda_function_environment_variables = {
    ENVIRONMENT                           = var.environment
    SENTRY_DSN                            = sentry_key.delphi_sentry_key.dsn_public
    DELPHI_SF_CREDENTIALS_SECRET_NAME     = aws_secretsmanager_secret.secrets["snowflake"].name
    DELPHI_SLZ_DB_CREDENTIALS_SECRET_NAME = "delphi/${var.environment}/slz/storage/pg_proxy/reader"
    DELPHI_MAIN_DB_CREDENTIALS            = "delphi/${var.environment}/api/pg/reader"
  }

  additional_tags = {
    "plat_env_project_service" = "DLP_${upper(var.environment)}_SLZ_LMB"
  }
}

# Create a sentry project.
resource "sentry_project" "delphi_sentry_project" {
  organization = var.sentry_organization
  teams        = var.sentry_teams
  name         = local.project_name
  slug         = local.project_slug
  platform     = var.sentry_platform
}

# Create a new key with a rate limit
# Sentry has it's own spike detection system but still
resource "sentry_key" "delphi_sentry_key" {
  organization = var.sentry_organization
  project      = sentry_project.delphi_sentry_project.slug

  name = "RateLimited"

  rate_limit_count  = "100"
  rate_limit_window = 3600 // 1 hour
}

# Retrieve a Slack integration
data "sentry_organization_integration" "slack_integration" {
  organization = var.sentry_organization

  provider_key = "slack"
  name         = var.slack_organization_name
}

resource "sentry_issue_alert" "delphi_sentry_issue_alert" {
  organization = var.sentry_organization
  project      = sentry_project.delphi_sentry_project.slug
  name         = "Send a notification for new and repeated issues"

  action_match = "any"
  filter_match = "any"
  frequency    = 1440

  conditions = jsonencode([
    # A new issue is created
    {
      id = "sentry.rules.conditions.first_seen_event.FirstSeenEventCondition"
    },
    # The issue is seen more than 10 times in one hour
    {
      id             = "sentry.rules.conditions.event_frequency.EventFrequencyCondition"
      value          = 10
      comparisonType = "count"
      interval       = "1h"
    },
    # The issue is seen more than 100 times in one day
    {
      id             = "sentry.rules.conditions.event_frequency.EventFrequencyCondition"
      value          = 100
      comparisonType = "count"
      interval       = "1d"
    },
    # The issue is seen more than 1000 times in one week
    {
      id             = "sentry.rules.conditions.event_frequency.EventFrequencyCondition"
      value          = 1000
      comparisonType = "count"
      interval       = "1w"
    },
  ])

  actions = jsonencode([
    # Send a notification to the Slack workspace to #general
    {
      id         = "sentry.integrations.slack.notify_action.SlackNotifyServiceAction"
      channel    = var.slack_channel_name
      channel_id = var.slack_channel_id
      tags       = join(",", var.notification_tags)
      workspace  = data.sentry_organization_integration.slack_integration.internal_id
    },
  ])
}

resource "aws_secretsmanager_secret" "secrets" {
  for_each = toset(var.secrets)

  name       = "${var.application_family}/${var.environment}/${var.service_name}/${each.value}"
  kms_key_id = data.aws_kms_key.secrets_general_key.id

  tags = {
    plat_env_project_service = "DLP_${upper(var.environment)}_SLZ_SCRT"
  }
}
