module "s3_shared_tf_states" {
  source = "../../modules/s3/private_bucket_with_logs_aes256_v2"

  bucket_name        = "${local.name_prefix}-shared-tf-states"
  logs_bucket_id     = data.aws_s3_bucket.security_logs.id
  logs_object_prefix = "${local.env_prefix}/shared-tf-states/"
  kms_master_key_id  = aws_kms_key.shared_tf.arn
  versioning         = true
  default_policy     = true

  common_tags = merge(local.common_tags,
    {
      Name                     = "${local.name_prefix}-shared-tf-states",
      service                  = "S3",
      plat_env_project_service = "${local.aggregated_tag}_S3"
    }
  )
}

data "aws_iam_policy_document" "kms_shared_tf" {
  statement {
    sid    = "Enable IAM User Permissions"
    effect = "Allow"
    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
    }
    actions   = ["kms:*"]
    resources = ["*"]
  }
}

resource "aws_kms_key" "shared_tf" {
  description         = "KMS key for shared terraform state bucket."
  enable_key_rotation = true
  tags                = local.common_tags
  policy              = data.aws_iam_policy_document.kms_shared_tf.json
}

resource "aws_kms_alias" "shared_tf" {
  name          = "alias/shared_tf"
  target_key_id = aws_kms_key.shared_tf.key_id
}

locals {
  shared_tf_path_placeholder = "%configs_path%"
}

data "aws_dynamodb_table" "tf_lock" {
  name = "terraform-state-lock-dynamodb"
}

data "aws_iam_policy_document" "iam_shared_tf_ro_policy_template" {
  statement {
    sid    = "AllowKmsKeyUsage"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:GenerateDataKey"
    ]
    resources = [aws_kms_key.shared_tf.arn]
  }
  statement {
    sid    = "AllowDynamodbLockTableUsage"
    effect = "Allow"
    actions = [
      "dynamodb:DescribeTable",
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:DeleteItem"
    ]
    resources = [data.aws_dynamodb_table.tf_lock.arn]
  }
  statement {
    sid    = "AllowBucketOperations"
    effect = "Allow"
    actions = [
      "s3:GetBucketLocation",
      "s3:ListBucket",
    ]
    resources = [module.s3_shared_tf_states.arn]
  }
  statement {
    sid       = "AllowBucketObjectOperations"
    effect    = "Allow"
    actions   = ["s3:GetObject*"]
    resources = ["${module.s3_shared_tf_states.arn}/${local.shared_tf_path_placeholder}"]
  }
}

data "aws_iam_policy_document" "iam_shared_tf_rw_policy_template" {
  statement {
    sid    = "AllowKmsKeyUsage"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:GenerateDataKey"
    ]
    resources = [aws_kms_key.shared_tf.arn]
  }
  statement {
    sid    = "AllowDynamodbLockTableUsage"
    effect = "Allow"
    actions = [
      "dynamodb:DescribeTable",
      "dynamodb:GetItem",
      "dynamodb:PutItem",
      "dynamodb:DeleteItem"
    ]
    resources = [data.aws_dynamodb_table.tf_lock.arn]
  }
  statement {
    sid    = "AllowBucketOperations"
    effect = "Allow"
    actions = [
      "s3:GetBucketLocation",
      "s3:ListBucket",
    ]
    resources = [module.s3_shared_tf_states.arn]
  }
  statement {
    sid    = "AllowBucketObjectOperations"
    effect = "Allow"
    actions = [
      "s3:GetObject*",
      "s3:PutObject*",
    ]
    resources = ["${module.s3_shared_tf_states.arn}/${local.shared_tf_path_placeholder}"]
  }
}

## Databricks shared tf group
resource "aws_iam_policy" "shared_tf_rw_databricks" {
  name   = "${local.name_prefix}-shared-tf-rw-databricks"
  policy = replace(data.aws_iam_policy_document.iam_shared_tf_rw_policy_template.json, local.shared_tf_path_placeholder, "databricks/")
}

resource "aws_iam_policy" "shared_tf_ro_databricks" {
  name   = "${local.name_prefix}-shared-tf-ro-databricks"
  policy = replace(data.aws_iam_policy_document.iam_shared_tf_ro_policy_template.json, local.shared_tf_path_placeholder, "databricks/")
}

resource "aws_iam_group" "shared_tf_databricks" {
  name = "shared-tf-databricks-rw"
}

resource "aws_iam_group_policy_attachment" "shared_tf_databricks" {
  group      = aws_iam_group.shared_tf_databricks.name
  policy_arn = aws_iam_policy.shared_tf_rw_databricks.arn
}
