###################################
## Outbox Processor Lambda & Schedule
###################################

# Build and package the outbox processor Lambda
# LocalStack Community Edition doesn't need ECR - we can use local Docker images directly
resource "null_resource" "build_outbox_processor" {
  triggers = {
    handler_hash = filemd5("${path.module}/../../lambda/outbox-processor/handler.py")
    dockerfile_hash = filemd5("${path.module}/../../lambda/outbox-processor/Dockerfile")
  }

  provisioner "local-exec" {
    command = <<-EOT
      cd ${path.module}/../../lambda/outbox-processor
      docker build --platform linux/amd64 -t outbox-processor:latest .
    EOT
  }
}

# IAM role for outbox processor Lambda
resource "aws_iam_role" "outbox_processor_lambda" {
  name = "${var.environment}-outbox-processor-lambda-role"

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

  tags = local.common_tags
}

# Policy for CloudWatch Logs
resource "aws_iam_role_policy" "outbox_processor_logs" {
  name = "${var.environment}-outbox-processor-logs"
  role = aws_iam_role.outbox_processor_lambda.id

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

# Policy for EventBridge
resource "aws_iam_role_policy" "outbox_processor_eventbridge" {
  name = "${var.environment}-outbox-processor-eventbridge"
  role = aws_iam_role.outbox_processor_lambda.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "events:PutEvents"
        ]
        Resource = "arn:aws:events:${var.aws_region}:*:event-bus/default"
      }
    ]
  })
}

# Lambda function for outbox processor
# LocalStack supports local Docker images using the format "local-image:tag"
resource "aws_lambda_function" "outbox_processor" {
  depends_on = [null_resource.build_outbox_processor]

  function_name = "${var.environment}-outbox-processor"
  role          = aws_iam_role.outbox_processor_lambda.arn
  package_type  = "Image"
  image_uri     = "outbox-processor:latest"
  timeout       = 60
  memory_size   = 512

  environment {
    variables = {
      DB_HOST           = "host.docker.internal"  # Access host's MySQL from Lambda
      DB_PORT           = "6050"
      DB_NAME           = "royalty_accounting"
      DB_USER           = "royalties"
      DB_PASSWORD       = "1234"
      BATCH_SIZE        = "100"
      AWS_ENDPOINT_URL  = "http://host.docker.internal:4566"
      EVENT_SOURCE      = "ows-royalties.outbox"
      # Disable Datadog tracing in local environment
      DD_TRACE_ENABLED = "false"
      DD_INSTRUMENTATION_TELEMETRY_ENABLED = "false"
    }
  }

  tags = local.common_tags
}

# CloudWatch Log Group for Lambda
resource "aws_cloudwatch_log_group" "outbox_processor" {
  name              = "/aws/lambda/${aws_lambda_function.outbox_processor.function_name}"
  retention_in_days = 7

  tags = local.common_tags
}

# EventBridge rule to trigger outbox processor (every minute)
# Note: AWS EventBridge rate() expressions don't support seconds - minimum is 1 minute
resource "aws_cloudwatch_event_rule" "outbox_processor_schedule" {
  name                = "${var.environment}-outbox-processor-schedule"
  description         = "Trigger outbox processor every minute"
  schedule_expression = "rate(1 minute)"

  tags = local.common_tags
}

# EventBridge target to invoke Lambda
resource "aws_cloudwatch_event_target" "outbox_processor_target" {
  rule      = aws_cloudwatch_event_rule.outbox_processor_schedule.name
  target_id = "OutboxProcessorLambda"
  arn       = aws_lambda_function.outbox_processor.arn
}

# Permission for EventBridge to invoke Lambda
resource "aws_lambda_permission" "allow_eventbridge_outbox_processor" {
  statement_id  = "AllowExecutionFromEventBridge"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.outbox_processor.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.outbox_processor_schedule.arn
}

###################################
## Downstream Event Handlers
###################################

# EventBridge rule to capture file_upload.completed events
resource "aws_cloudwatch_event_rule" "file_upload_completed" {
  name        = "${var.environment}-file-upload-completed"
  description = "Capture file upload completed events from outbox"

  event_pattern = jsonencode({
    source      = ["ows-royalties.outbox"]
    detail-type = ["file_upload.completed"]
  })

  tags = local.common_tags
}

# CloudWatch Logs target for observability (optional)
resource "aws_cloudwatch_log_group" "outbox_events" {
  name              = "/aws/events/${var.environment}-outbox-events"
  retention_in_days = 7

  tags = local.common_tags
}

resource "aws_cloudwatch_event_target" "file_upload_completed_logs" {
  rule      = aws_cloudwatch_event_rule.file_upload_completed.name
  target_id = "LogTarget"
  arn       = aws_cloudwatch_log_group.outbox_events.arn
}

###################################
## Example Downstream Handler Lambda
###################################

# Build and package the file upload handler Lambda
# LocalStack Community Edition doesn't need ECR - we can use local Docker images directly
resource "null_resource" "build_file_upload_handler" {
  triggers = {
    handler_hash = filemd5("${path.module}/../../lambda/file-upload-handler/handler.py")
    dockerfile_hash = filemd5("${path.module}/../../lambda/file-upload-handler/Dockerfile")
  }

  provisioner "local-exec" {
    command = <<-EOT
      cd ${path.module}/../../lambda/file-upload-handler
      docker build --platform linux/amd64 -t file-upload-handler:latest .
    EOT
  }
}

# IAM role for file upload handler Lambda
resource "aws_iam_role" "file_upload_handler_lambda" {
  name = "${var.environment}-file-upload-handler-lambda-role"

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

  tags = local.common_tags
}

# Policy for CloudWatch Logs
resource "aws_iam_role_policy" "file_upload_handler_logs" {
  name = "${var.environment}-file-upload-handler-logs"
  role = aws_iam_role.file_upload_handler_lambda.id

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

# Lambda function for file upload handler
# LocalStack supports local Docker images using the format "local-image:tag"
resource "aws_lambda_function" "file_upload_handler" {
  depends_on = [null_resource.build_file_upload_handler]

  function_name = "${var.environment}-file-upload-handler"
  role          = aws_iam_role.file_upload_handler_lambda.arn
  package_type  = "Image"
  image_uri     = "file-upload-handler:latest"
  timeout       = 30
  memory_size   = 256

  environment {
    variables = {
      # Disable Datadog tracing in local environment
      DD_TRACE_ENABLED = "false"
      DD_INSTRUMENTATION_TELEMETRY_ENABLED = "false"
    }
  }

  tags = local.common_tags
}

# CloudWatch Log Group for file upload handler Lambda
resource "aws_cloudwatch_log_group" "file_upload_handler" {
  name              = "/aws/lambda/${aws_lambda_function.file_upload_handler.function_name}"
  retention_in_days = 7

  tags = local.common_tags
}

# EventBridge target to invoke file upload handler Lambda
resource "aws_cloudwatch_event_target" "file_upload_handler_target" {
  rule      = aws_cloudwatch_event_rule.file_upload_completed.name
  target_id = "FileUploadHandlerLambda"
  arn       = aws_lambda_function.file_upload_handler.arn
}

# Permission for EventBridge to invoke file upload handler Lambda
resource "aws_lambda_permission" "allow_eventbridge_file_upload_handler" {
  statement_id  = "AllowExecutionFromEventBridge"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.file_upload_handler.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.file_upload_completed.arn
}

# Outputs
output "outbox_processor_function_name" {
  value = aws_lambda_function.outbox_processor.function_name
}

output "outbox_processor_log_group" {
  value = aws_cloudwatch_log_group.outbox_processor.name
}

output "file_upload_handler_function_name" {
  value = aws_lambda_function.file_upload_handler.function_name
}

output "file_upload_handler_log_group" {
  value = aws_cloudwatch_log_group.file_upload_handler.name
}

output "outbox_events_log_group" {
  value = aws_cloudwatch_log_group.outbox_events.name
}
