
resource "aws_api_gateway_rest_api" "fan_response_rest_api" {
  name        = "${var.environment}-${var.service_name}"
  description = "Fan Response and campaigns REST API Gateway"
  endpoint_configuration {
    types = ["EDGE"]
  }
  lifecycle {
    create_before_destroy = true
  }
  tags = {
    application_family = var.application_family
    environment        = var.environment
    service_name       = var.service_name
    terraformed        = true
  }
}

resource "aws_api_gateway_stage" "sme_fan_response_rest_api_stage" {
  deployment_id         = aws_api_gateway_deployment.fan_response_rest_api_deployment.id
  rest_api_id           = aws_api_gateway_rest_api.fan_response_rest_api.id
  stage_name            = var.environment
  client_certificate_id = aws_api_gateway_client_certificate.fan_response_rest_api_client_certificate.id

  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.fan_response_rest_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",
      "integrationErrorMessage" : "$context.integrationErrorMessage"
    })
  }
}

resource "aws_api_gateway_method_settings" "smf_response_api_gateway_method_settings" {
  rest_api_id = aws_api_gateway_rest_api.fan_response_rest_api.id
  stage_name  = aws_api_gateway_stage.sme_fan_response_rest_api_stage.stage_name
  method_path = "*/*"

  settings {
    metrics_enabled = true
    logging_level   = "INFO"
  }
}

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

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

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

  name = var.route53_zone_name
}

resource "aws_api_gateway_domain_name" "smf_rest_api_domain_name" {
  domain_name              = "${var.environment}-${var.service_name}.${data.aws_route53_zone.route53_zone.name}"
  regional_certificate_arn = data.aws_acm_certificate.tls_cert.arn
  security_policy          = "TLS_1_2"

  endpoint_configuration {
    types = ["REGIONAL"]
  }

  tags = local.tags
}

resource "aws_route53_record" "smf_rest_api_route53_record" {
  name    = aws_api_gateway_domain_name.smf_rest_api_domain_name.domain_name
  type    = "A"
  zone_id = data.aws_route53_zone.route53_zone.id

  alias {
    evaluate_target_health = true
    name                   = aws_api_gateway_domain_name.smf_rest_api_domain_name.regional_domain_name
    zone_id                = aws_api_gateway_domain_name.smf_rest_api_domain_name.regional_zone_id
  }
}

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

  name    = aws_api_gateway_domain_name.smf_rest_api_domain_name.domain_name
  type    = "A"
  zone_id = data.aws_route53_zone.route53_zone_networking.id

  alias {
    evaluate_target_health = true
    name                   = aws_api_gateway_domain_name.smf_rest_api_domain_name.regional_domain_name
    zone_id                = aws_api_gateway_domain_name.smf_rest_api_domain_name.regional_zone_id
  }
}

resource "aws_api_gateway_base_path_mapping" "smf_rest_api_path_mapping" {
  api_id      = aws_api_gateway_rest_api.fan_response_rest_api.id
  stage_name  = aws_api_gateway_stage.sme_fan_response_rest_api_stage.stage_name
  domain_name = aws_api_gateway_domain_name.smf_rest_api_domain_name.domain_name
}

# NLB for VPC Link
# Traffic flow: API Gateway -> VPC Link -> NLB -> ALB -> OWS DMP backend
resource "aws_lb" "ows_dmp_nlb" {
  name               = "${var.environment}-ows-dmp-nlb"
  internal           = true
  load_balancer_type = "network"
  subnets            = module.vpc_info.default_private_subnet_ids

  enable_deletion_protection       = false
  enable_cross_zone_load_balancing = true

  access_logs {
    bucket  = "orch-elb-logs"
    enabled = true
    prefix  = "${var.environment}-ows-dmp-nlb"
  }

  tags = merge(
    local.tags,
    {
      Name = "${var.environment}-ows-dmp-nlb"
    }
  )
}

# Target group pointing to the ALB
resource "aws_lb_target_group" "ows_dmp_nlb_to_alb" {
  name        = "${var.environment}-ows-dmp-nlb-tg"
  port        = 443
  protocol    = "TCP"
  target_type = "alb"
  vpc_id      = var.vpc_id

  health_check {
    enabled             = true
    healthy_threshold   = 3
    interval            = 30
    protocol            = "HTTPS"
    path                = "/hello/"
    matcher             = "200"
    unhealthy_threshold = 3
  }

  tags = merge(
    local.tags,
    {
      Name = "${var.environment}-ows-dmp-nlb-tg"
    }
  )
}

# Attach ALB to target group
resource "aws_lb_target_group_attachment" "ows_dmp_alb_to_nlb" {
  target_group_arn = aws_lb_target_group.ows_dmp_nlb_to_alb.arn
  target_id        = data.aws_lb.ows_dmp_alb.arn
  port             = 443
}

# NLB listener forwarding to target group
resource "aws_lb_listener" "ows_dmp_nlb_listener" {
  load_balancer_arn = aws_lb.ows_dmp_nlb.arn
  port              = 443
  protocol          = "TCP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.ows_dmp_nlb_to_alb.arn
  }
}

# VPC Link v1 for REST API Gateway
resource "aws_api_gateway_vpc_link" "fan_response_vpc_link" {
  name        = "${local.prefix}-ows-dmp-vpc-link"
  target_arns = [aws_lb.ows_dmp_nlb.arn]

  tags = merge(
    local.tags,
    {
      Name = "${local.prefix}-ows-dmp-vpc-link"
    }
  )
}
