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

  default_tags {
    tags = module.default_tags.tags
  }
}

provider "aws" {
  region  = var.aws_region
  alias   = "networking"
  profile = "networking"

  default_tags {
    tags = module.default_tags.tags
  }
}

data "aws_caller_identity" "current" {}

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

module "gda_signup_lambda_sentry" {
  source             = "git@github.com:theorchard/terraform-sentry.git//?ref=4.1.2"
  environment        = var.environment
  platform           = "python"
  service_name       = var.lambda_name
  application_family = var.application_family
}

module "gda_signup_lambda_datadog" {
  source                            = "git@github.com:theorchard/terraform-datadog.git//modules/lambda?ref=6.13.6"
  environment                       = var.environment
  service_name                      = var.lambda_name
  lambda_invocation_monitor_enabled = false
}

data "aws_msk_cluster" "msk_cluster" {
  cluster_name = var.msk_cluster_name
}

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

  environment                                       = var.environment
  lambda_name                                       = var.lambda_name
  lambda_description                                = "Send GDA submission requests coming from the landing website into Kafka topic."
  application_family                                = var.application_family
  use_container_image                               = true
  lambda_function_provisioned_concurrent_executions = var.lambda_provisioned_concurrent_executions
  datadog_advanced_enabled                          = var.datadog_advanced_enabled

  vpc_id                  = var.vpc_id
  vpc_subnet_ids          = var.vpc_subnet_ids
  dlq_enabled             = var.dlq_enabled
  zappa_s3_policy_enabled = false

  lambda_function_environment_variables = {
    ENVIRONMENT               = var.environment
    BOOTSTRAP_SERVERS         = data.aws_msk_cluster.msk_cluster.bootstrap_brokers_tls
    TOPIC_NAME                = var.kafka_topic
    KAFKA_API_VERSION         = data.aws_msk_cluster.msk_cluster.kafka_version
    DD_LAMBDA_HANDLER         = var.lambda_handler
    SALESFORCE_RECORD_TYPE_ID = var.salesforce_record_type_id
    SENTRY_DSN                = module.gda_signup_lambda_sentry.sentry_key_dsn_public_output
  }
}

resource "aws_apigatewayv2_api" "gda_signup_api" {
  name          = "${var.environment}-${var.service_name}"
  protocol_type = "HTTP"
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

resource "aws_cloudwatch_log_group" "gda_signup_api_log_group" {
  name              = "/aws/apigateway/${var.environment}-${var.service_name}"
  retention_in_days = 365
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

resource "aws_apigatewayv2_stage" "gda_signup_api_stage" {
  api_id      = aws_apigatewayv2_api.gda_signup_api.id
  name        = "${var.environment}-${var.service_name}-stage"
  auto_deploy = true
  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.gda_signup_api_log_group.arn
    format          = jsonencode({ "requestId" : "$context.requestId", "ip" : "$context.identity.sourceIp", "caller" : "$context.identity.caller", "user" : "$context.identity.user", "requestTime" : "$context.requestTime", "httpMethod" : "$context.httpMethod", "resourcePath" : "$context.resourcePath", "status" : "$context.status", "protocol" : "$context.protocol", "responseLength" : "$context.responseLength" })
  }
}

resource "aws_lambda_permission" "gda_signup_lambda_api_gateway_permission" {
  statement_id  = "AllowAPIGatewayInvoke"
  action        = "lambda:InvokeFunction"
  function_name = module.lambda_gda_submit.lambda_arn
  qualifier     = module.lambda_gda_submit.lambda_qualifier
  principal     = "apigateway.amazonaws.com"
  source_arn    = "${aws_apigatewayv2_api.gda_signup_api.execution_arn}/*"
}

resource "aws_apigatewayv2_integration" "gda_signup_api_lambda" {
  api_id                 = aws_apigatewayv2_api.gda_signup_api.id
  integration_type       = "AWS_PROXY"
  integration_method     = "POST"
  integration_uri        = module.lambda_gda_submit.lambda_invoke_arn
  payload_format_version = "2.0"
}

resource "aws_apigatewayv2_authorizer" "gda_signup_api_auth0_authorizer" {
  api_id           = aws_apigatewayv2_api.gda_signup_api.id
  authorizer_type  = "JWT"
  identity_sources = ["$request.header.Authorization"]
  name             = "${var.environment}-gda-auth0-authorizer"

  jwt_configuration {
    audience = [var.auth0_authorizer_audience]
    issuer   = var.auth0_authorizer_issuer
  }
}

resource "aws_apigatewayv2_route" "gda_signup_api_route" {
  api_id             = aws_apigatewayv2_api.gda_signup_api.id
  route_key          = "POST /artist-submission"
  target             = "integrations/${aws_apigatewayv2_integration.gda_signup_api_lambda.id}"
  authorization_type = "JWT"
  authorizer_id      = aws_apigatewayv2_authorizer.gda_signup_api_auth0_authorizer.id
}

data "aws_acm_certificate" "certificate" {
  domain   = var.acm_certificate_domain
  statuses = ["ISSUED"]
}

data "aws_route53_zone" "route53_zone" {
  name = var.route53_zone_name
}

data "aws_route53_zone" "networking_route53_zone" {
  provider = aws.networking

  name = var.route53_zone_name
}

resource "aws_apigatewayv2_domain_name" "gda_signup_api_domain" {
  domain_name = var.domain_name

  domain_name_configuration {
    certificate_arn = data.aws_acm_certificate.certificate.arn
    endpoint_type   = "REGIONAL"
    security_policy = "TLS_1_2"
  }
}

resource "aws_route53_record" "gda_signup_api_route53_record" {
  name    = aws_apigatewayv2_domain_name.gda_signup_api_domain.domain_name
  type    = "A"
  zone_id = data.aws_route53_zone.route53_zone.zone_id

  alias {
    name                   = aws_apigatewayv2_domain_name.gda_signup_api_domain.domain_name_configuration[0].target_domain_name
    zone_id                = aws_apigatewayv2_domain_name.gda_signup_api_domain.domain_name_configuration[0].hosted_zone_id
    evaluate_target_health = false
  }
}

resource "aws_route53_record" "gda_signup_api_networking_route53_record" {
  provider = aws.networking

  name    = aws_apigatewayv2_domain_name.gda_signup_api_domain.domain_name
  type    = "A"
  zone_id = data.aws_route53_zone.networking_route53_zone.zone_id

  alias {
    name                   = aws_apigatewayv2_domain_name.gda_signup_api_domain.domain_name_configuration[0].target_domain_name
    zone_id                = aws_apigatewayv2_domain_name.gda_signup_api_domain.domain_name_configuration[0].hosted_zone_id
    evaluate_target_health = false
  }
}

resource "aws_apigatewayv2_api_mapping" "gda_signup_api_mapping" {
  api_id      = aws_apigatewayv2_api.gda_signup_api.id
  domain_name = aws_apigatewayv2_domain_name.gda_signup_api_domain.id
  stage       = aws_apigatewayv2_stage.gda_signup_api_stage.id
}

resource "aws_cloudwatch_log_subscription_filter" "datadog_lambda_function_log_filter" {
  count           = var.api_gateway_access_logs_enabled ? 1 : 0
  name            = "${var.environment}-${var.service_name}-subscription-filter"
  log_group_name  = aws_cloudwatch_log_group.gda_signup_api_log_group.name
  filter_pattern  = ""
  destination_arn = local.datadog_function_destination_arn
  distribution    = "ByLogStream"
}
