resource "snowflake_account_role" "schema_read_role" {
  for_each = var.enable_account_roles ? { for k, v in local.schemas_by_name : k => v if v.create_roles } : {}

  name    = coalesce(each.value.read_role_name, "${snowflake_database.db.name}_DB_${each.value.name}_SCHEMA_READ")
  comment = "Managed by Terraform"
}

resource "snowflake_grant_ownership" "schema_read_account_role_ownership" {
  for_each = snowflake_account_role.schema_read_role

  account_role_name   = "USERADMIN"
  outbound_privileges = "COPY"
  on {
    object_type = "ROLE"
    object_name = each.value.name
  }
}

resource "snowflake_grant_account_role" "schema_read_role_grants" {
  for_each = var.grant_roles_to_sysadmin ? snowflake_account_role.schema_read_role : {}

  role_name        = each.value.name
  parent_role_name = "SYSADMIN"
}

resource "snowflake_grant_privileges_to_account_role" "schema_read_role_database_grants" {
  for_each = snowflake_account_role.schema_read_role

  privileges        = local.db_read_privileges
  account_role_name = each.value.name

  on_account_object {
    object_type = "DATABASE"
    object_name = snowflake_database.db.name
  }
}

resource "snowflake_grant_privileges_to_account_role" "schema_read_role_schema_grants" {
  for_each = var.enable_account_roles ? { for k, v in local.schemas_by_name : k => snowflake_schema.schema[k] if v.create_roles } : {}

  privileges        = local.schema_read_privileges
  account_role_name = snowflake_account_role.schema_read_role[each.value.name].name

  on_schema {
    schema_name = "\"${snowflake_database.db.name}\".\"${each.value.name}\""
  }
}

module "schema_read_account_role_object_grants" {
  for_each = var.enable_account_roles ? local.schema_object_privileges : {}
  source   = "../../internal/schema_object_grants"

  database_name      = snowflake_database.db.name
  object_type_plural = each.key
  schema_role_map    = { for k, v in local.schemas_by_name : k => snowflake_account_role.schema_read_role[k].name if v.create_roles }
  role_type          = "account"
  privileges         = each.value.read
}

############### DATABASE ROLES ################
resource "snowflake_database_role" "schema_read_role" {
  for_each = var.enable_database_roles ? { for k, v in local.schemas_by_name : k => v if v.create_roles } : {}

  name     = coalesce(each.value.read_role_name, "DB_${each.value.name}_SCHEMA_READ")
  database = snowflake_database.db.name
  comment  = "Managed by Terraform"
}

resource "snowflake_grant_ownership" "schema_read_role_ownership" {
  for_each = snowflake_database_role.schema_read_role

  account_role_name   = "USERADMIN"
  outbound_privileges = "COPY"
  on {
    object_type = "DATABASE ROLE"
    object_name = "${snowflake_database.db.name}.${each.value.name}"
  }
}

resource "snowflake_grant_database_role" "schema_read_role_grants" {
  for_each = var.grant_roles_to_sysadmin ? snowflake_database_role.schema_read_role : {}

  database_role_name = "${snowflake_database.db.name}.${each.value.name}"
  parent_role_name   = "SYSADMIN"
}

resource "snowflake_grant_privileges_to_database_role" "schema_read_role_database_grants" {
  for_each = snowflake_database_role.schema_read_role

  privileges         = local.db_read_privileges
  database_role_name = "${snowflake_database.db.name}.${each.value.name}"
  on_database        = snowflake_database.db.name
}

resource "snowflake_grant_privileges_to_database_role" "schema_read_role_schema_grants" {
  for_each = var.enable_database_roles ? { for k, v in local.schemas_by_name : k => snowflake_schema.schema[k] if v.create_roles } : {}

  privileges         = local.schema_read_privileges
  database_role_name = "${snowflake_database.db.name}.${snowflake_database_role.schema_read_role[each.value.name].name}"

  on_schema {
    schema_name = "\"${snowflake_database.db.name}\".\"${each.value.name}\""
  }
}

module "schema_read_database_role_object_grants" {
  for_each = var.enable_database_roles ? local.schema_object_privileges : {}
  source   = "../../internal/schema_object_grants"

  database_name      = snowflake_database.db.name
  object_type_plural = each.key
  schema_role_map    = { for k, v in local.schemas_by_name : k => snowflake_database_role.schema_read_role[k].name if v.create_roles }
  role_type          = "database"
  privileges         = each.value.read
}
