# step functions
locals {
  sfn_name = "workflow-tools-bulk-asset-download"
}

data "aws_iam_policy_document" "assume_statemachines_role" {
  statement {
    actions = ["sts:AssumeRole"]

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

resource "aws_iam_role" "bulk_asset_download_state_machine_role" {
  name               = format("%s-%s-state-machine-role", var.environment, local.sfn_name)
  assume_role_policy = data.aws_iam_policy_document.assume_statemachines_role.json

  tags = module.default_tags.tags
}

resource "aws_sfn_state_machine" "bulk_asset_download_state_machine" {
  name     = format("%s-%s-sfn", var.environment, local.sfn_name)
  role_arn = aws_iam_role.bulk_asset_download_state_machine_role.arn
  definition = templatefile(
    "workflow_tools_bulk_asset_download.json",
    {
      subnet_id0 = module.vpc_info.default_private_subnet_ids[0],
      subnet_id1 = module.vpc_info.default_private_subnet_ids[1],

      input_bucket_name = module.bulk_asset_download_input_bucket.s3_bucket_name_output,

      lambda_get_asset_locations_arn      = module.lambda_get_asset_locations.lambda_arn,
      lambda_get_products_for_account_arn = module.lambda_get_products_for_account.lambda_arn,
      lambda_generate_error_report_arn    = module.lambda_generate_error_report.lambda_arn,

      fargate_asset_copy_cluster_arn = module.asset_copy_worker_fargate_environment.fargate_cluster_arn,
      fargate_asset_copy_task_arn    = module.asset_copy_worker_fargate_environment.fargate_task_definition_arn_without_revision,
      fargate_asset_copy_worker_name = format("%s-%s", var.service_name, var.asset_copy_worker_name),
      sns_topic_arn                  = module.sfn_notifications.topic_arn
    }
  )

  tags = module.default_tags.tags

  logging_configuration {
    log_destination        = format("%s:*", aws_cloudwatch_log_group.bulk_asset_download_sfn_log_group.arn)
    include_execution_data = true
    level                  = "ERROR"
  }

  tracing_configuration {
    enabled = true
  }
}

resource "aws_cloudwatch_log_group" "bulk_asset_download_sfn_log_group" {
  name              = format("%s-%s-log-group", var.environment, local.sfn_name)
  retention_in_days = 365
  tags = module.default_tags.tags
}

data "awscc_events_rule" "sfn_get_events_for_ecs_task_rule" {
  id = "StepFunctionsGetEventsForECSTaskRule"
}

data "aws_iam_policy_document" "ecs_task_execution_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "ecs:RunTask",
      "ecs:StopTask",
      "ecs:DescribeTasks",
    ]
    resources = [
      module.asset_copy_worker_fargate_environment.fargate_task_definition_arn_without_revision,
      format("%s:*", module.asset_copy_worker_fargate_environment.fargate_task_definition_arn_without_revision),
    ]
  }

  statement {
    effect = "Allow"
    actions = [
      "events:PutTargets",
      "events:PutRule",
      "events:DescribeRule"
    ]
    resources = [
      data.awscc_events_rule.sfn_get_events_for_ecs_task_rule.arn,
    ]
  }


  statement {
    effect = "Allow"
    actions = [
      "iam:PassRole",
    ]
    resources = [
      module.asset_copy_worker_fargate_environment.fargate_task_iam_role_arn,
      module.asset_copy_worker_fargate_environment.fargate_task_iam_execution_role_arn,
    ]
  }
}

resource "aws_iam_role_policy" "ecs_task_execution_policy" {
  name   = format("ECS-%s-%s-ExecutionOnly", var.environment, local.sfn_name)
  role   = aws_iam_role.bulk_asset_download_state_machine_role.id
  policy = data.aws_iam_policy_document.ecs_task_execution_policy_document.json
}

# Step Function (SFN) - SFN Cloudwatch logs permission policy
data "aws_iam_policy_document" "sfn_log_event_policy_document" {
  statement {
    effect = "Allow"
    resources = [
      aws_cloudwatch_log_group.bulk_asset_download_sfn_log_group.arn,
      format("%s:*", aws_cloudwatch_log_group.bulk_asset_download_sfn_log_group.arn),
      format("%s:log-stream:*", aws_cloudwatch_log_group.bulk_asset_download_sfn_log_group.arn),
    ]

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

  statement {
    effect    = "Allow"
    resources = ["*"]
    actions = [
      "logs:CreateLogDelivery",
      "logs:DeleteLogDelivery",
      "logs:DescribeLogGroups",
      "logs:DescribeResourcePolicies",
      "logs:GetLogDelivery",
      "logs:ListLogDeliveries",
      "logs:PutResourcePolicy",
      "logs:UpdateLogDelivery",
    ]
  }
}

resource "aws_iam_policy" "sfn_log_event_policy" {
  name        = format("%s-%s-log-event-policy", var.environment, local.sfn_name)
  description = "Policy for Step Function to write logs to CloudWatch"
  policy = data.aws_iam_policy_document.sfn_log_event_policy_document.json
}

resource "aws_iam_role_policy_attachment" "sfn_log_event_policy_attachment" {
  role       = aws_iam_role.bulk_asset_download_state_machine_role.name
  policy_arn = aws_iam_policy.sfn_log_event_policy.arn
}

# State machine publish SNS message policy
data "aws_iam_policy_document" "sfn_sns_notification_publish_message_policy" {
  statement {
    actions = [
      "sns:Publish",
    ]

    resources = [
      module.sfn_notifications.topic_arn,
    ]
  }
}

resource "aws_iam_role_policy" "sfn_sns_notification_publish_message_role_policy" {
  name   = "${var.environment}-${var.bulk_asset_download_tool_name}-publish-sns-notification-policy"
  role   = aws_iam_role.bulk_asset_download_state_machine_role.id
  policy = data.aws_iam_policy_document.sfn_sns_notification_publish_message_policy.json
}

# State machine lambda invocation policy
data "aws_iam_policy_document" "bulk_asset_download_invoke_lambda_policy" {
  statement {
    actions = [
      "lambda:InvokeFunction",
    ]

    resources = [
      module.lambda_get_asset_locations.lambda_arn,
      module.lambda_get_products_for_account.lambda_arn,
      module.lambda_generate_error_report.lambda_arn,
    ]
  }
}

resource "aws_iam_role_policy" "bulk_asset_download_invoke_lambda_role_policy" {
  name   = format("%s-bulk-asset-download-sfn-lambda-role-policy", var.environment)
  role   = aws_iam_role.bulk_asset_download_state_machine_role.id
  policy = data.aws_iam_policy_document.bulk_asset_download_invoke_lambda_policy.json
}

resource "aws_iam_role_policy_attachment" "bulk_asset_download_s3_write_role_policy" {
  role       = aws_iam_role.bulk_asset_download_state_machine_role.id
  policy_arn = aws_iam_policy.s3_bulk_asset_download_input_bucket_access_policy.arn
}

# State machine execute sfn policy
data "aws_iam_policy_document" "bulk_asset_download_execute_sfn_policy_doc" {
  statement {
    actions = [
      "states:StartExecution",
    ]

    resources = [
      aws_sfn_state_machine.bulk_asset_download_state_machine.id,
    ]
  }
}

resource "aws_iam_policy" "bulk_asset_download_execute_sfn_policy" {
  name   = format("%s-%s-sfn-scheduler-policy", var.environment, local.sfn_name)
  policy = data.aws_iam_policy_document.bulk_asset_download_execute_sfn_policy_doc.json
}

resource "aws_iam_role_policy_attachment" "bulk_asset_download_execute_sfn_policy_attachment" {
  policy_arn = aws_iam_policy.bulk_asset_download_execute_sfn_policy.arn
  role       = aws_iam_role.bulk_asset_download_state_machine_role.id
}
