locals {
  db_read_privileges     = toset(["MONITOR", "USAGE"])
  schema_read_privileges = toset(["MONITOR", "USAGE"])

  schemas = toset([for schema_objects in var.schema_objects_by_type_and_privileges : schema_objects.schema])

  objects_flat = toset(flatten([
    for schema_objects in var.schema_objects_by_type_and_privileges : [
      for name in schema_objects.objects :
      {
        schema      = schema_objects.schema,
        type        = schema_objects.type,
        object_name = name,
        privileges  = schema_objects.privileges,
      }
    ]
  ]))
}

resource "snowflake_database_role" "role" {
  name     = "DB_${var.role_name_suffix}"
  database = var.database_name
  comment  = "Managed by Terraform"
}

resource "snowflake_grant_ownership" "db_role_ownership" {
  account_role_name   = "USERADMIN"
  outbound_privileges = "COPY"
  on {
    object_type = "DATABASE ROLE"
    object_name = "${var.database_name}.${snowflake_database_role.role.name}"
  }
}

resource "snowflake_grant_database_role" "grant_to_sysadmin" {
  database_role_name = "${var.database_name}.${snowflake_database_role.role.name}"
  parent_role_name   = "SYSADMIN"
}

resource "snowflake_grant_privileges_to_database_role" "database_grants" {
  privileges         = local.db_read_privileges
  database_role_name = "${var.database_name}.${snowflake_database_role.role.name}"
  on_database        = var.database_name
}

resource "snowflake_grant_privileges_to_database_role" "schema_grants" {
  for_each           = local.schemas
  privileges         = local.schema_read_privileges
  database_role_name = "${var.database_name}.${snowflake_database_role.role.name}"

  on_schema {
    schema_name = "\"${var.database_name}\".\"${each.value}\""
  }
}

resource "snowflake_grant_privileges_to_database_role" "schema_object_grants" {
  for_each = { for obj in local.objects_flat : "${obj.schema}_${obj.type}_${obj.object_name}" => obj if length(obj.privileges) > 0 }

  privileges         = each.value.privileges
  database_role_name = "${var.database_name}.${snowflake_database_role.role.name}"

  on_schema_object {
    object_type = upper(each.value.type)
    object_name = "\"${var.database_name}\".\"${each.value.schema}\".\"${each.value.object_name}\""
  }
}
