resource "aws_iam_role" "this" {
  name                  = var.name
  path                  = "/service/"
  force_detach_policies = true # causes "DeleteConflict" if not present

  tags = merge(var.standard_tags, var.tags)

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": ${jsonencode(var.trusted_arns)}
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "this" {
  role       = aws_iam_role.this.name
  policy_arn = aws_iam_policy.this.arn
}

resource "aws_iam_policy" "this" {
  name        = var.name
  path        = "/service/"
  description = var.description
  policy      = length(var.kms_key_ids) == 0 ? data.aws_iam_policy_document.base_policy.json : data.aws_iam_policy_document.kms_policy.json

  tags        = merge(var.standard_tags, var.tags)
}

data "aws_iam_policy_document" "base_policy" {
  statement {
    sid    = "ReadTheBucket"
    effect = "Allow"
    resources = [
      var.bucket
    ]

    actions = [
      "s3:ListBucket",
      "s3:GetBucketLocation",
      "s3:ListBucketMultipartUploads",
      "s3:ListBucketVersions",
    ]
  }

  statement {
    sid    = "ModifyBucketObjects"
    effect = "Allow"
    resources = [
      "${var.bucket}/*"
    ]

    actions = [
      "s3:GetObject",
      "s3:DeleteObject",
      "s3:AbortMultipartUpload",
      "s3:ListMultipartUploadParts",
    ]
  }

  statement {
    sid    = "RequireWritesToGiveBucketOwnerControl"
    effect = "Allow"
    resources = [
      "${var.bucket}/*"
    ]

    actions = [
      "s3:PutObject"
    ]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
  }
}

data "aws_iam_policy_document" "kms_policy" {
  source_json = data.aws_iam_policy_document.base_policy.json

  statement {
    sid       = "UseTheKMSKey"
    effect    = "Allow"
    resources = var.kms_key_ids
    actions = [
      "kms:GenerateDataKey",
      "kms:Encrypt",
      "kms:Decrypt",
      "kms:DescribeKey"
    ]
  }
}
