locals {
  all_users = merge(
    { for user in var.read_only_users : "${user.user}_readonly" => merge(user, { user_type = "read_only_users" }) },
    { for user in var.read_write_users : "${user.user}_readwrite" => merge(user, { user_type = "read_write_users" }) }
  )

    custom_role_users = { for user in var.custom_role_users : "${user.user}_custom" => merge(user, { user_type = "custom_role_users" }) }
}

resource "mysql_user" "all_predefined_role_users" {
  for_each = local.all_users

  user        = each.value.user
  host        = lookup(each.value, "host_identifier", var.host_identifier)
  auth_plugin = each.value.auth_plugin
  tls_option  = each.value.auth_plugin == "AWSAuthenticationPlugin" ? "SSL" : var.tls_option_enforced
}

resource "mysql_user" "custom_role_users" {
  for_each = local.custom_role_users

  user        = each.value.user
  host        = lookup(each.value, "host_identifier", var.host_identifier)
  auth_plugin = each.value.auth_plugin
  tls_option  = each.value.auth_plugin == "AWSAuthenticationPlugin" ? "SSL" : var.tls_option_enforced
}

resource "mysql_role" "all_roles" {
  for_each = toset(var.roles)
  name     = each.value
}

resource "mysql_grant" "all_role_privileges" {
  for_each = {
    "read_only_role"         = { role = mysql_role.all_roles["read_only_role"].name, privileges = var.read_only_role_privileges },
    "read_write_role"        = { role = mysql_role.all_roles["read_write_role"].name, privileges = var.read_write_role_privileges },
  }
  role       = each.value.role
  database   = var.database_name
  privileges = each.value.privileges
}

resource "mysql_grant" "user_roles" {
  for_each = local.all_users

  user     = each.value.user
  host     = lookup(each.value, "host_identifier", var.host_identifier)
  database = var.database_name
  roles = concat(
    [
      lookup(
        {
          "read_only_users"  = mysql_role.all_roles["read_only_role"].name,
          "read_write_users" = mysql_role.all_roles["read_write_role"].name,
        },
        each.value.user_type,
        ""
      )
    ]
  )
}

resource "mysql_grant" "custom_user_roles" {
  for_each = local.custom_role_users

  user     = each.value.user
  host     = lookup(each.value, "host_identifier", var.host_identifier)
  database = var.database_name
  roles    = [for role in each.value.roles : mysql_role.custom_roles[role].name]

  depends_on = [mysql_user.custom_role_users]
}

resource "mysql_default_roles" "all_predefined_default_roles" {
  for_each = local.all_users

  user = each.value.user
  host = lookup(each.value, "host_identifier", var.host_identifier)
  roles = concat(
    [
      lookup(
        {
          "read_only_users"  = mysql_role.all_roles["read_only_role"].name,
          "read_write_users" = mysql_role.all_roles["read_write_role"].name,
        },
        each.value.user_type,
        ""
      )
    ]
  )

  depends_on = [
    mysql_user.all_predefined_role_users,
    mysql_grant.user_roles
  ]
}

resource "mysql_default_roles" "custom_user_default_roles" {
  for_each = local.custom_role_users

  user = each.value.user
  host = lookup(each.value, "host_identifier", var.host_identifier)
  roles = [for role in each.value.roles : mysql_role.custom_roles[role].name]

  depends_on = [
    mysql_user.custom_role_users,
    mysql_grant.custom_user_roles
  ]
}

resource "mysql_role" "custom_roles" {
  for_each = var.custom_roles

  name = each.value.name
}

resource "mysql_grant" "custom_role_privileges" {
  for_each   = { for idx, role in var.custom_roles : idx => role }
  role       = mysql_role.custom_roles[each.key].name
  database   = var.database_name
  privileges = each.value.privileges
}