# Step Function (SFN) root role policy document
data "aws_iam_policy_document" "sfn_altafonte_user_creation_assume_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["states.amazonaws.com"]
    }
  }
}

# Create iam role
resource "aws_iam_role" "sfn_altafonte_user_creation_assume_role" {
  name               = "${var.environment}-workflow-${var.service_name}-state-machine-role"
  assume_role_policy = data.aws_iam_policy_document.sfn_altafonte_user_creation_assume_role_policy.json
  tags               = local.tags
}

# Cloudwatch logs permission policy
data "aws_iam_policy_document" "sfn_altafonte_user_creation_log_event_policy_document" {
  statement {
    effect = "Allow"
    resources = [
      "arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:log-group:${var.environment}-${var.service_name}",
      "arn:aws:logs:${var.aws_region}:${data.aws_caller_identity.current.account_id}:log-group:${var.environment}-${var.service_name}:log-stream:*"
    ]

    actions = [
      "logs:CreateLogGroup",
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ]
  }
}

# Attach log policy
resource "aws_iam_role_policy" "sfn_altafonte_user_creation_log_event_policy_attachment" {
  name   = "${var.environment}-${var.service_name}-log-event-policy"
  role   = aws_iam_role.sfn_altafonte_user_creation_assume_role.id
  policy = data.aws_iam_policy_document.sfn_altafonte_user_creation_log_event_policy_document.json
}

# Tracing permission policy
data "aws_iam_policy_document" "sfn_altafonte_user_creation_xray_policy_document" {
  statement {
    effect    = "Allow"
    resources = ["*"]

    actions = [
      "xray:PutTraceSegments",
      "xray:PutTelemetryRecords",
      "xray:GetSamplingRules",
      "xray:GetSamplingTargets"
    ]
  }
}

# Attach tracing policy
resource "aws_iam_role_policy" "sfn_altafonte_user_creation_xray_role_policy" {
  name   = "${var.environment}-${var.service_name}-xray-role-policy"
  role   = aws_iam_role.sfn_altafonte_user_creation_assume_role.id
  policy = data.aws_iam_policy_document.sfn_altafonte_user_creation_xray_policy_document.json
}

# Attach s3 policy created by terraform-s3 module in main.tf
resource "aws_iam_role_policy_attachment" "s3_role_policy" {
  role       = aws_iam_role.sfn_altafonte_user_creation_assume_role.name
  policy_arn = module.s3_bucket.s3_read_only_policy_arn_output
}

# State machine lambda policy that gives the state machine role permission to invoke lambdas
data "aws_iam_policy_document" "sfn_altafonte_user_creation_invoke_lambda_policy_document" {
  statement {
    actions = [
      "lambda:InvokeFunction",
    ]

    resources = [
      module.lambda_create_altafonte_user.lambda_arn,
      module.lambda_send_success.lambda_arn,
      module.lambda_send_failure.lambda_arn,
    ]
  }
}

# Attach invoke lambda policy
resource "aws_iam_role_policy" "sfn_altafonte_user_creation_invoke_lambda_role_policy" {
  name   = "${var.environment}-${var.service_name}-lambda-role-policy"
  role   = aws_iam_role.sfn_altafonte_user_creation_assume_role.id
  policy = data.aws_iam_policy_document.sfn_altafonte_user_creation_invoke_lambda_policy_document.json
}

# State machine
data "template_file" "altafonte_user_creation_definition" {
  template = file("${path.module}/altafonte_user_creation.json")
  vars = {
    bucket_name                  = module.s3_bucket.s3_bucket_name_output
    lambda_create_user_arn       = module.lambda_create_altafonte_user.lambda_arn
    lambda_send_success_arn      = module.lambda_send_success.lambda_arn
    lambda_send_failure_arn      = module.lambda_send_failure.lambda_arn
    lambda_retry_attempts        = var.lambda_retry_attempts
    lambda_interval_seconds      = var.lambda_interval_seconds
    tolerated_failure_percentage = var.tolerated_failure_percentage
    max_concurrency              = var.max_concurrency
  }
}

resource "aws_sfn_state_machine" "altafonte_user_creation" {
  name       = "${var.environment}-workflow-${var.service_name}"
  role_arn   = aws_iam_role.sfn_altafonte_user_creation_assume_role.arn
  definition = data.template_file.altafonte_user_creation_definition.rendered
  tags       = local.tags
  tracing_configuration {
    enabled = true
  }
}

# Invoke step function policy.  Necessary to run Distributed Map state
data "aws_iam_policy_document" "invoke_step_function_policy_document" {
  statement {
    actions = [
      "states:StartExecution",
      "states:ListExecutions",
    ]

    resources = [
      aws_sfn_state_machine.altafonte_user_creation.arn
    ]
  }
}

# Attach invoke step function policy
resource "aws_iam_role_policy" "sfn_invoke_step_function_policy" {
  name   = "${var.environment}-${var.service_name}-step-functions-policy"
  role   = aws_iam_role.sfn_altafonte_user_creation_assume_role.id
  policy = data.aws_iam_policy_document.invoke_step_function_policy_document.json
}

module "statemachine_dd_integration" {
  source = "git@github.com:theorchard/terraform-datadog.git//modules/step-function?ref=6.13.0"

  statemachine_arn   = aws_sfn_state_machine.altafonte_user_creation.arn
  environment        = var.environment
  service_name       = var.service_name
  application_family = var.application_family

  notification_endpoints            = var.slack_alert_channel
  escalation_notification_endpoints = var.slack_alert_channel

  failed_execution_metric_monitor_enabled = true
  # 5 min evaluation window; default of 1m was not working for us
  statemachine_failed_metric_monitor_window = 5
}
