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

provider "aws" {
  region = "us-east-1"

  default_tags {
    tags = module.default_tags.tags
  }
}

data "aws_caller_identity" "current" {}

terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "qa/lambda-notifications/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

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

  environment = var.environment
}


moved {
  from = aws_iam_policy.dynamodb_policy
  to   = aws_iam_policy.lambda_notification_event_buffer_dynamodb_policy
}

module "lambda_push_delivery_failure_owsrequest" {
  source = "git@github.com:theorchard/terraform-owsrequest.git?ref=1.1.0"

  environment_name = var.environment
  service_name     = "lambda-notifications-push-delivery-failure"
}

data "aws_iam_policy_document" "sns_endpoint_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "sns:GetEndpointAttributes"
    ]
    resources = [
      "arn:aws:sns:us-east-1:437795906767:app/APNS/QA_Orchard_Go",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/QA_Orchard_Go_FCM",
      "arn:aws:sns:us-east-1:437795906767:app/APNS/qa-awal",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/qa-awal",
      "arn:aws:sns:us-east-1:437795906767:app/APNS/qa-sme",
      "arn:aws:sns:us-east-1:437795906767:app/GCM/qa-sme"
    ]
  }
}

resource "aws_iam_policy" "sns_endpoint_policy" {
  name   = "${var.environment}-sns-push-endpoint-delivery-failure-lambda-policy"
  policy = data.aws_iam_policy_document.sns_endpoint_policy_document.json
}

module "lambda-push-delivery-failure" {
  source = "git@github.com:theorchard/terraform-lambda.git?ref=4.3.0"

  application_family       = var.application_family
  use_container_image      = true
  datadog_advanced_enabled = true
  environment              = var.environment
  lambda_name              = "push-delivery-failure"
  lambda_description       = "Reacts to EventDeliveryFailure messages from SNS push notifications"
  lambda_function_timeout  = var.lambda_timeout

  vpc_enabled    = true
  vpc_id         = module.vpc_info.vpc_id
  vpc_subnet_ids = module.vpc_info.default_private_subnet_ids

  iam_managed_policy_attachments = [
    module.lambda_push_delivery_failure_owsrequest.policy_arn_output,
    aws_iam_policy.sns_endpoint_policy.arn
  ]
  lambda_function_reserved_concurrent_executions = "3"
  lambda_function_environment_variables = {
    Environment = var.environment
  }
}

module "sentry-push-delivery-failure" {
  source = "git@github.com:theorchard/terraform-sentry.git?ref=4.1.2"

  application_family = var.application_family
  environment        = var.environment
  platform           = "python"
  service_name       = "push-delivery-failure"
}

module "sns-push-delivery-failure" {
  source = "git@github.com:theorchard/terraform-sns.git?ref=3.1.0"

  environment               = var.environment
  application_family        = var.application_family
  sns_topic_name            = "push-delivery-failure"
  sns_subscription_enabled  = true
  sns_subscription_endpoint = module.lambda-push-delivery-failure.lambda_arn
}

resource "aws_lambda_permission" "allow_proxy_sns_messages" {
  statement_id  = "${var.environment}-trigger-lambda-from-sns-for-push-delivery-failure"
  action        = "lambda:InvokeFunction"
  function_name = module.lambda-push-delivery-failure.lambda_name
  principal     = "sns.amazonaws.com"
  source_arn    = module.sns-push-delivery-failure.topic_arn
}

module "fanout_event_queue" {
  source = "git@github.com:theorchard/terraform-sqs.git?ref=2.4.1"

  environment                    = var.environment
  queue_name                     = var.fanout_queue_name
  application_family             = var.application_family
  sqs_message_retention_seconds  = 10800
  sqs_visibility_timeout_seconds = 360
  sqs_max_message_size           = 262144
  sqs_fifo_queue                 = "false"

  sqs_deadletter_enabled = "true"

  deadletter_message_retention_seconds = 86400
  deadletter_max_receive_count         = 5
  deadletter_delay_seconds             = 10
  deadletter_max_message_size          = 262144
  deadletter_receive_wait_time_seconds = 10
}

module "push_notifications_queue" {
  source = "git@github.com:theorchard/terraform-sqs.git?ref=2.4.1"

  environment                    = var.environment
  queue_name                     = var.queue_name
  application_family             = var.application_family
  sqs_message_retention_seconds  = 10800
  sqs_visibility_timeout_seconds = 360
  sqs_max_message_size           = 262144
  sqs_fifo_queue                 = "false"

  sqs_deadletter_enabled = "true"

  deadletter_message_retention_seconds = 86400
  deadletter_max_receive_count         = 1
  deadletter_delay_seconds             = 10
  deadletter_max_message_size          = 262144
  deadletter_receive_wait_time_seconds = 10
}

data "aws_iam_policy_document" "getstream_role_policy" {
  statement {

    sid = ""

    actions = [
      "sqs:SendMessage",
      "sqs:SendMessageBatch",
      "sqs:GetQueueUrl",
      "sqs:GetQueueAttributes"
    ]

    resources = [
      module.push_notifications_queue.queue_arn
    ]
  }
}

resource "aws_iam_policy" "getstream_iam_policy" {
  name   = "${var.environment}-getstream-policy"
  policy = data.aws_iam_policy_document.getstream_role_policy.json
}

module "lambda_fanout_event_owsrequest" {
  source = "git@github.com:theorchard/terraform-owsrequest.git?ref=1.1.0"

  environment_name = var.environment
  service_name     = "lambda-notifications-fanout-event"
}

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

  application_family       = var.application_family
  use_container_image      = true
  datadog_advanced_enabled = true
  environment              = var.environment
  lambda_name              = "fanout-event"
  lambda_description       = "SQS triggers a call to fanout events into GetStream"
  lambda_function_timeout  = var.lambda_timeout

  vpc_enabled    = true
  vpc_id         = module.vpc_info.vpc_id
  vpc_subnet_ids = module.vpc_info.default_private_subnet_ids

  iam_managed_policy_attachments = [
    module.lambda_fanout_event_owsrequest.policy_arn_output
  ]
  event_source_mapping_queue_name                = "${var.environment}-${var.fanout_queue_name}-queue"
  event_source_mapping_batch_size                = 10
  sqs_event_enabled                              = true
  lambda_function_reserved_concurrent_executions = "4"
  lambda_function_environment_variables = {
    Environment = var.environment
  }
}

module "lambda_publish_message_owsrequest" {
  source = "git@github.com:theorchard/terraform-owsrequest.git?ref=1.1.0"

  environment_name = var.environment
  service_name     = "lambda-notifications-publish-message"
}

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

  application_family       = var.application_family
  use_container_image      = true
  datadog_advanced_enabled = true
  environment              = var.environment
  lambda_name              = "publish-message"
  lambda_description       = "SQS triggers a publish call to user SNS topic"
  lambda_function_timeout  = var.lambda_timeout

  vpc_enabled    = true
  vpc_id         = module.vpc_info.vpc_id
  vpc_subnet_ids = module.vpc_info.default_private_subnet_ids


  iam_managed_policy_attachments = [
    module.lambda_publish_message_owsrequest.policy_arn_output
  ]
  event_source_mapping_queue_name                = "${var.environment}-${var.queue_name}-queue"
  event_source_mapping_batch_size                = 10
  sqs_event_enabled                              = true
  iam_policy_file_enabled                        = true
  lambda_function_reserved_concurrent_executions = "4"
  lambda_function_environment_variables = {
    Environment      = var.environment,
    BUFFER_POLLER_ID = module.lambda_buffer_poller.lambda_role_unique_id,
  }
}

module "sentry_fanout_event" {
  source = "git@github.com:theorchard/terraform-sentry.git?ref=4.1.2"

  application_family = var.application_family
  environment        = var.environment
  platform           = "python"
  service_name       = "fanout-event"
}

module "sentry_publish_message" {
  source = "git@github.com:theorchard/terraform-sentry.git?ref=4.1.2"

  application_family = var.application_family
  environment        = var.environment
  platform           = "python"
  service_name       = "publish-message"
}

module "notification_event_buffer_dynamo_table" {
  source                         = "git@github.com:theorchard/terraform-dynamodb.git//?ref=3.3.1"
  env                            = var.environment
  application_family             = var.application_family
  use_on_demand                  = true
  server_side_encryption_enabled = true
  table_name                     = "notifications-buffer"
  hash_key                       = var.event_buffer_dynamo_table_hash_key

  attribute = [
    {
      name = var.event_buffer_dynamo_table_hash_key
      type = "S"
    }
  ]
}

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

  application_family       = var.application_family
  environment              = var.environment
  use_container_image      = true
  datadog_advanced_enabled = true
  lambda_name              = "buffer-poller"
  lambda_description       = "Polls dynamodb and writes to SQS"
  lambda_function_timeout  = var.lambda_timeout

  vpc_enabled    = true
  vpc_id         = module.vpc_info.vpc_id
  vpc_subnet_ids = module.vpc_info.default_private_subnet_ids

  iam_managed_policy_attachments = [
    module.lambda_buffer_poller_owsrequest.policy_arn_output,
    aws_iam_policy.sqs_send_message_policy.arn,
    aws_iam_policy.lambda_notification_event_buffer_dynamodb_policy.arn
  ]
  lambda_function_reserved_concurrent_executions = "3"
  lambda_function_environment_variables = {
    Environment                = var.environment,
    PUSH_NOTIFICATIONS_SQS_URL = module.push_notifications_queue.queue_url
  }
}

data "aws_iam_policy_document" "sqs_send_message_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "sqs:SendMessage",
      "sqs:SendMessageBatch"
    ]
    resources = [
      module.push_notifications_queue.queue_arn
    ]
  }
}

resource "aws_iam_policy" "sqs_send_message_policy" {
  name   = "${var.environment}-sqs-send-message-buffer-poller-lambda-policy"
  policy = data.aws_iam_policy_document.sqs_send_message_policy_document.json
}

data "aws_iam_policy_document" "lambda_notification_event_buffer_dynamodb_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "dynamodb:Scan"
    ]
    resources = [
      module.notification_event_buffer_dynamo_table.aws_dynamodb_table_arn
    ]
  }
}

resource "aws_iam_policy" "lambda_notification_event_buffer_dynamodb_policy" {
  name   = "${var.environment}-dynamodb-buffer-poller-lambda-policy"
  policy = data.aws_iam_policy_document.lambda_notification_event_buffer_dynamodb_policy_document.json
}

module "lambda_buffer_poller_owsrequest" {
  source = "git@github.com:theorchard/terraform-owsrequest.git?ref=1.1.0"

  environment_name = var.environment
  service_name     = "lambda-notifications-buffer-poller"
}

module "sentry-buffer-poller" {
  source = "git@github.com:theorchard/terraform-sentry.git?ref=4.1.2"

  application_family = var.application_family
  environment        = var.environment
  platform           = "python"
  service_name       = "buffer-poller"
}

resource "aws_cloudwatch_event_rule" "buffer_poller_event" {
  name                = "${var.environment}-buffer-poller-event"
  description         = "Event for polling dynamodb buffer table"
  schedule_expression = "rate(15 minutes)"
}

resource "aws_cloudwatch_event_target" "buffer_poller_event_target" {
  rule      = aws_cloudwatch_event_rule.buffer_poller_event.name
  target_id = "${var.environment}-buffer-poller-event"
  arn       = module.lambda_buffer_poller.lambda_arn
  input     = "{\"eventType\": \"poll-buffer\"}"
}

resource "aws_lambda_permission" "allow_cloudwatch_buffer_poller_event" {
  statement_id  = "AllowBufferPollerExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = module.lambda_buffer_poller.lambda_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.buffer_poller_event.arn
}
