data "aws_iam_policy_document" "assume_role_policy" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "AWS"
      identifiers = var.assume_role_principals
    }
    # Enforce use of AWS username for role session name for auditing purposes
    condition {
      test     = "StringLike"
      variable = "sts:RoleSessionName"
      values = [
        "$${aws:username}"
      ]
    }
    # Enforce MFA
    condition {
      test     = "Bool"
      variable = "aws:MultiFactorAuthPresent"
      values = [
        "true",
      ]
    }
  }
}

resource "aws_iam_role" "role" {
  name                 = var.role_name
  assume_role_policy   = data.aws_iam_policy_document.assume_role_policy.json
  max_session_duration = var.max_session_duration

  tags = {
    terraformed = true
  }
}

# Get data sources for all application family policies to which this role should have access
data "aws_iam_policy" "application_family_abac_policies" {
  for_each = {
    for policy in local.abac_policies_to_attach : policy.policy_name => policy
  }
  name = each.value.policy_name
}

data "aws_iam_policy" "application_family_rbac_policies" {
  for_each = {
    for policy in local.rbac_policies_to_attach : policy.policy_name => policy
  }
  name = each.value.policy_name
}

# Attach the ABAC and RBAC policies
resource "aws_iam_role_policy_attachment" "abac_policy_attachments" {
  for_each   = data.aws_iam_policy.application_family_abac_policies
  role       = aws_iam_role.role.name
  policy_arn = each.value.arn
}

resource "aws_iam_role_policy_attachment" "rbac_policy_attachments" {
  for_each   = data.aws_iam_policy.application_family_rbac_policies
  role       = aws_iam_role.role.name
  policy_arn = each.value.arn
}

data "aws_iam_policy" "additional_policies" {
  for_each = var.additional_policies_to_attach
  name     = each.value
}

resource "aws_iam_role_policy_attachment" "additional_policy_attachments" {
  for_each   = data.aws_iam_policy.additional_policies
  role       = aws_iam_role.role.name
  policy_arn = each.value.arn
}

data "aws_iam_policy_document" "role_access_policy" {
  count = var.iam_roles_to_access == null ? 0 : 1

  statement {
    actions = [
      "sts:AssumeRole",
    ]

    resources = var.iam_roles_to_access
  }
}

resource "aws_iam_policy" "role_access_policy" {
  count = var.iam_roles_to_access == null ? 0 : 1

  name   = "${var.role_name}-role-access-policy"
  policy = data.aws_iam_policy_document.role_access_policy[0].json
}

resource "aws_iam_role_policy_attachment" "role_access_policy_attachment" {
  count      = var.iam_roles_to_access == null ? 0 : 1

  policy_arn = aws_iam_policy.role_access_policy[0].arn
  role       = aws_iam_role.role.name
}
