# IAM Role for Lambda Function
resource "aws_iam_role" "dsp_visualizer_lambda_role" {
  provider = aws.eu-central-1
  name     = "dspVisualizer-lambda-role"

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

  tags = merge(
    var.tags,
    {
      Name    = "dspVisualizer-lambda-role"
      Purpose = "Lambda-Execution"
    }
  )
}

# CloudWatch Logs Policy for Lambda
resource "aws_iam_policy" "lambda_cloudwatch_logs_policy" {
  provider    = aws.eu-central-1
  name        = "dspVisualizer-lambda-cloudwatch-logs"
  description = "IAM policy for Lambda CloudWatch Logs permissions"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource = "arn:aws:logs:${var.region}:${var.account_id}:*"
      }
    ]
  })

  tags = merge(
    var.tags,
    {
      Name = "dspVisualizer-lambda-cloudwatch-logs"
    }
  )
}

# Attach CloudWatch Logs Policy to Lambda Role
resource "aws_iam_role_policy_attachment" "lambda_logs_attachment" {
  provider   = aws.eu-central-1
  role       = aws_iam_role.dsp_visualizer_lambda_role.name
  policy_arn = aws_iam_policy.lambda_cloudwatch_logs_policy.arn
}

# Attach AWS Managed Basic Execution Role Policy
resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
  provider   = aws.eu-central-1
  role       = aws_iam_role.dsp_visualizer_lambda_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# CloudWatch Log Group for Lambda Function
resource "aws_cloudwatch_log_group" "dsp_visualizer_lambda_logs" {
  #checkov:skip=CKV_AWS_338: Ensure CloudWatch log groups retains logs for at least 1 year
  provider          = aws.eu-central-1
  name              = "/aws/lambda/${var.lambda_function_name}"
  retention_in_days = var.lambda_log_retention_days

  tags = merge(
    var.tags,
    {
      Name    = "${var.lambda_function_name}-logs"
      Purpose = "Lambda-Logs"
    }
  )
}

# Lambda Function
resource "aws_lambda_function" "dsp_visualizer" {
  #checkov:skip=CKV_AWS_115: Ensure that AWS Lambda function is configured for function-level concurrent execution limit
  #checkov:skip=CKV_AWS_117: Ensure that AWS Lambda function is configured inside a VPC
  #checkov:skip=CKV_AWS_50: X-Ray tracing is enabled for Lambda
  #checkov:skip=CKV_AWS_173: Check encryption settings for Lambda environmental variable
  #checkov:skip=CKV_AWS_116: Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)
  provider      = aws.eu-central-1
  function_name = var.lambda_function_name
  role          = aws_iam_role.dsp_visualizer_lambda_role.arn
  handler       = var.lambda_handler
  runtime       = var.lambda_runtime
  timeout       = var.lambda_timeout
  memory_size   = var.lambda_memory_size

  # Sample Hello World code
  filename         = data.archive_file.lambda_zip.output_path
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256

  environment {
    variables = var.lambda_environment_variables
  }

  depends_on = [
    aws_iam_role_policy_attachment.lambda_logs_attachment,
    aws_cloudwatch_log_group.dsp_visualizer_lambda_logs,
  ]

  tags = merge(
    var.tags,
    {
      Name    = var.lambda_function_name
      Purpose = "DSP-Visualizer"
    }
  )
}

# Create inline Lambda code
locals {
  lambda_code = <<-EOT
    exports.handler = async (event) => {
        console.log('Event:', JSON.stringify(event, null, 2));
        
        // CORS headers
        const headers = {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Methods': 'POST,OPTIONS'
        };
        
        // Handle OPTIONS request for CORS preflight
        if (event.httpMethod === 'OPTIONS') {
            return {
                statusCode: 200,
                headers: headers,
                body: JSON.stringify({ message: 'CORS preflight response' })
            };
        }
        
        // Handle POST request
        const response = {
            statusCode: 200,
            headers: headers,
            body: JSON.stringify({
                message: 'Hello World from DSP Visualizer Lambda!',
                timestamp: new Date().toISOString(),
                requestId: event.requestContext ? event.requestContext.requestId : 'N/A'
            }),
        };
        
        return response;
    };
  EOT
}

# Create a zip file for the Lambda function code
data "archive_file" "lambda_zip" {
  type        = "zip"
  output_path = "/tmp/dsp_visualizer_lambda.zip"

  source {
    content  = local.lambda_code
    filename = "index.js"
  }
}
