# Terraform configuration to create a simple Step Functions state machine.

provider "aws" {
  region = "us-east-1"
}

# --- 1. Lambda Function ---
# Create dummy Lambda code
resource "local_file" "lambda_code" {
  content = <<EOF
import json

def lambda_handler(event, context):
    print(f"Received event: {json.dumps(event)}")
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Step Functions Lambda!')
    }
EOF
  filename = "${path.module}/hello_world_lambda.py"
}

# Archive the python script into a zip file
data "archive_file" "lambda_zip" {
  type        = "zip"
  source_file = local_file.lambda_code.filename
  output_path = "${path.module}/function.zip"
}

# IAM Role for Lambda
resource "aws_iam_role" "lambda_role" {
  name = "StepFunctionsHelloWorldLambdaRole"

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

resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
  role       = aws_iam_role.lambda_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_lambda_function" "hello_world" {
  function_name    = "StepFunctionsHelloWorld"
  handler          = "hello_world_lambda.lambda_handler"
  runtime          = "python3.9"
  role             = aws_iam_role.lambda_role.arn
  filename         = data.archive_file.lambda_zip.output_path
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256
  timeout          = 30
  memory_size      = 128

  depends_on = [aws_iam_role_policy_attachment.lambda_basic_execution]
}

# --- 2. IAM Role for Step Functions ---
resource "aws_iam_role" "sfn_role" {
  name = "MyTerraformStepFunctionsExecutionRole"

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

# Policy to allow Step Functions to invoke Lambda
resource "aws_iam_policy" "sfn_lambda_invoke_policy" {
  name        = "MyTerraformStepFunctionsLambdaInvokePolicy"
  description = "Allows Step Functions to invoke the Hello World Lambda"

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = ["lambda:InvokeFunction"],
        Resource = aws_lambda_function.hello_world.arn
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "sfn_lambda_invoke_attachment" {
  role       = aws_iam_role.sfn_role.name
  policy_arn = aws_iam_policy.sfn_lambda_invoke_policy.arn
}

# --- 3. Create State Machine ---
resource "aws_sfn_state_machine" "simple_state_machine" {
  name     = "MyTerraformSimpleStateMachine"
  role_arn = aws_iam_role.sfn_role.arn
  type     = "STANDARD"

  definition = jsonencode({
    Comment = "A simple state machine that invokes a Lambda function.",
    StartAt = "InvokeLambda",
    States = {
      InvokeLambda = {
        Type = "Task",
        Resource = "arn:aws:states:::lambda:invoke",
        Parameters = {
          FunctionName = aws_lambda_function.hello_world.arn,
          "Payload.$"  = "$"
        },
        End = true
      }
    }
  })

  depends_on = [aws_iam_role_policy_attachment.sfn_lambda_invoke_attachment]
}

# --- Outputs ---
output "state_machine_arn" {
  value       = aws_sfn_state_machine.simple_state_machine.id
  description = "The ARN of the Step Functions state machine."
}

output "lambda_function_name" {
  value       = aws_lambda_function.hello_world.function_name
  description = "The name of the Lambda function invoked by the state machine."
}
