# IAM Role for API Gateway CloudWatch Logging
resource "aws_iam_role" "api_gateway_cloudwatch_role" {
  provider = aws.eu-central-1
  name     = "api-gateway-cloudwatch-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "apigateway.amazonaws.com"
        }
      }
    ]
  })

  tags = {
    Name          = "api-gateway-cloudwatch-role"
    Environment   = "dev"
    Terraform     = "True"
    Business-Unit = "Digital-Supply-Chain"
    Project-Name  = "Switchboard"
    Project-Code  = "Switchboard"
  }
}

# Attach CloudWatch Logs policy to API Gateway role
resource "aws_iam_role_policy_attachment" "api_gateway_cloudwatch_policy" {
  provider   = aws.eu-central-1
  role       = aws_iam_role.api_gateway_cloudwatch_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"
}

# API Gateway Account settings to enable CloudWatch logging
resource "aws_api_gateway_account" "api_gateway_account" {
  provider            = aws.eu-central-1
  cloudwatch_role_arn = aws_iam_role.api_gateway_cloudwatch_role.arn

  depends_on = [
    aws_iam_role_policy_attachment.api_gateway_cloudwatch_policy
  ]
}

resource "aws_api_gateway_rest_api" "dsp_visualizer_api" {
  #checkov:skip=CKV_AWS_237: Ensure Create before destroy for API Gateway
  provider    = aws.eu-central-1
  name        = "dsp-visualizer-dev-api"
  description = "DSP Visualizer Development API Gateway"

  endpoint_configuration {
    types = ["REGIONAL"]
  }

  tags = {
    Name          = "dsp-visualizer-dev-api"
    Environment   = "dev"
    Terraform     = "True"
    Business-Unit = "Digital-Supply-Chain"
    Project-Name  = "Switchboard"
    Project-Code  = "Switchboard"
    Owner         = "Robert Dewilder"
    Purpose       = "API-SUPPORT"
  }
}

resource "aws_api_gateway_resource" "api_resource" {
  provider    = aws.eu-central-1
  rest_api_id = aws_api_gateway_rest_api.dsp_visualizer_api.id
  parent_id   = aws_api_gateway_rest_api.dsp_visualizer_api.root_resource_id
  path_part   = "api"
}

resource "aws_api_gateway_method" "post_method" {
  #checkov:skip=CKV2_AWS_53: Ensure AWS API gateway request is validated
  #checkov:skip=CKV_AWS_59: Ensure there is no open access to back-end resources through API
  provider      = aws.eu-central-1
  rest_api_id   = aws_api_gateway_rest_api.dsp_visualizer_api.id
  resource_id   = aws_api_gateway_resource.api_resource.id
  http_method   = "POST"
  authorization = "NONE"
}

# OPTIONS method for CORS preflight
resource "aws_api_gateway_method" "options_method" {
  #checkov:skip=CKV2_AWS_53: Ensure AWS API gateway request is validated
  provider      = aws.eu-central-1
  rest_api_id   = aws_api_gateway_rest_api.dsp_visualizer_api.id
  resource_id   = aws_api_gateway_resource.api_resource.id
  http_method   = "OPTIONS"
  authorization = "NONE"
}

# Construct Lambda ARN directly - no data source lookup needed
locals {
  lambda_invoke_arn = "arn:aws:apigateway:${var.region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${var.region}:${var.account_id}:function:${var.lambda_function_name}/invocations"
}

resource "aws_api_gateway_integration" "lambda_integration" {
  provider    = aws.eu-central-1
  rest_api_id = aws_api_gateway_rest_api.dsp_visualizer_api.id
  resource_id = aws_api_gateway_resource.api_resource.id
  http_method = aws_api_gateway_method.post_method.http_method

  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = local.lambda_invoke_arn
}

# OPTIONS method Lambda integration for CORS
resource "aws_api_gateway_integration" "options_integration" {
  provider    = aws.eu-central-1
  rest_api_id = aws_api_gateway_rest_api.dsp_visualizer_api.id
  resource_id = aws_api_gateway_resource.api_resource.id
  http_method = aws_api_gateway_method.options_method.http_method

  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = local.lambda_invoke_arn
}

resource "aws_api_gateway_deployment" "api_deployment" {
  provider    = aws.eu-central-1
  rest_api_id = aws_api_gateway_rest_api.dsp_visualizer_api.id

  triggers = {
    redeployment = sha1(jsonencode([
      aws_api_gateway_resource.api_resource.id,
      aws_api_gateway_method.post_method.id,
      aws_api_gateway_method.options_method.id,
      aws_api_gateway_integration.lambda_integration.id,
      aws_api_gateway_integration.options_integration.id,
    ]))
  }

  lifecycle {
    create_before_destroy = true
  }

  depends_on = [
    aws_api_gateway_method.post_method,
    aws_api_gateway_method.options_method,
    aws_api_gateway_integration.lambda_integration,
    aws_api_gateway_integration.options_integration
  ]
}

resource "aws_api_gateway_stage" "dev" {
  #checkov:skip=CKV2_AWS_29: Ensure public API gateway are protected by WAF
  #checkov:skip=CKV2_AWS_51: Ensure AWS API Gateway endpoints uses client certificate authentication
  #checkov:skip=CKV2_AWS_4: Ensure API Gateway stage have logging level defined as appropriate
  provider      = aws.eu-central-1
  deployment_id = aws_api_gateway_deployment.api_deployment.id
  rest_api_id   = aws_api_gateway_rest_api.dsp_visualizer_api.id
  stage_name    = "dev"

  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.api_gateway_logs.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"
    })
  }

  tags = {
    Name          = "dsp-visualizer-dev"
    Environment   = "dev"
    Terraform     = "True"
    Business-Unit = "Digital-Supply-Chain"
    Project-Name  = "Switchboard"
    Project-Code  = "Switchboard"
  }

  depends_on = [
    aws_api_gateway_account.api_gateway_account
  ]
}

resource "aws_cloudwatch_log_group" "api_gateway_logs" {
  #checkov:skip=CKV_AWS_338: Ensure CloudWatch log groups retains logs for at least 1 year
  provider          = aws.eu-central-1
  name              = "/aws/api-gateway/dsp-visualizer-dev"
  retention_in_days = 30

  tags = {
    Name          = "dsp-visualizer-api-logs"
    Environment   = "dev"
    Terraform     = "True"
    Business-Unit = "Digital-Supply-Chain"
    Project-Name  = "Switchboard"
    Project-Code  = "Switchboard"
  }
}

# Lambda permission for API Gateway to invoke the function
resource "aws_lambda_permission" "api_gateway_invoke" {
  provider      = aws.eu-central-1
  statement_id  = "AllowAPIGatewayInvoke-dsp-visualizer"
  action        = "lambda:InvokeFunction"
  function_name = var.lambda_function_name
  principal     = "apigateway.amazonaws.com"

  # The source ARN for the API Gateway
  source_arn = "${aws_api_gateway_rest_api.dsp_visualizer_api.execution_arn}/*/*"
}