provider "snowflake" {
  account_name = var.account
  role         = "SECURITYADMIN"
}


provider "snowflake" {
  alias        = "prod_atlantis"
  account_name = var.account
  role         = "PROD_ATLANTIS"
  warehouse    = "CICD_WH"
  preview_features_enabled = [
    "snowflake_user_authentication_policy_attachment_resource",
  ]
}

terraform {
  backend "s3" {
    bucket  = "orcd-terraform-state"
    key     = "prod/snowflake/delphidev/service_users/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

resource "snowflake_service_user" "service_users" {
  for_each = var.service_users

  name         = each.key
  login_name   = each.key
  display_name = each.key
  comment      = each.value.comment
  disabled     = each.value.disabled ? "true" : "false"
  email        = each.value.email

  network_policy = each.value.network_policy

  default_warehouse              = each.value.default_wh
  default_role                   = each.value.default_role
  default_namespace              = each.value.default_namespace
  default_secondary_roles_option = each.value.default_secondary_roles_option

  rsa_public_key = each.value.rsa_public_key

  lifecycle {
    ignore_changes = [mins_to_unlock, show_output]
  }
}

resource "snowflake_grant_ownership" "service_users" {
  for_each          = var.service_users
  account_role_name = each.value.owner

  on {
    object_type = "USER"
    object_name = snowflake_service_user.service_users[each.key].name
  }
}

resource "snowflake_legacy_service_user" "legacy_service_users" {
  for_each = var.legacy_service_users

  name         = each.key
  login_name   = each.key
  display_name = each.key
  comment      = each.value.comment
  disabled     = each.value.disabled ? "true" : "false"
  email        = each.value.email

  network_policy = each.value.network_policy

  default_warehouse              = each.value.default_wh
  default_role                   = each.value.default_role
  default_namespace              = each.value.default_namespace
  default_secondary_roles_option = each.value.default_secondary_roles_option

  rsa_public_key = each.value.rsa_public_key

  lifecycle {
    ignore_changes = [password, must_change_password, show_output, parameters, display_name, mins_to_unlock]
  }
}

resource "snowflake_grant_ownership" "legacy_service_users" {
  for_each          = var.legacy_service_users
  account_role_name = each.value.owner

  on {
    object_type = "USER"
    object_name = snowflake_legacy_service_user.legacy_service_users[each.key].name
  }
}


locals {
  service_user_roles = { for user, props in var.service_users :
    user => props.roles
  }
  legacy_service_user_roles = { for user, props in var.legacy_service_users :
    user => props.roles
  }

  role_grants = merge([
    for role, users in transpose(merge(local.service_user_roles, local.legacy_service_user_roles)) :
    { for user in users : "${role}_${user}" => { "role" = role, "user" = user }
  }]...)
}

resource "snowflake_grant_account_role" "role_grants" {
  for_each  = local.role_grants
  role_name = each.value.role
  user_name = try(snowflake_service_user.service_users[each.value.user].name, snowflake_legacy_service_user.legacy_service_users[each.value.user].name)
}

# Authentication policy attachments
resource "snowflake_user_authentication_policy_attachment" "service_users" {
  for_each                   = var.service_users
  provider                   = snowflake.prod_atlantis
  authentication_policy_name = "\"SNOWFLAKE_SETTINGS\".\"AUTHENTICATION_POLICIES\".\"service_users_authentication_policy\""
  user_name                  = snowflake_service_user.service_users[each.key].name
}

resource "snowflake_user_authentication_policy_attachment" "legacy_service_users" {
  for_each                   = var.legacy_service_users
  provider                   = snowflake.prod_atlantis
  authentication_policy_name = "\"SNOWFLAKE_SETTINGS\".\"AUTHENTICATION_POLICIES\".\"legacy_users_authentication_policy\""
  user_name                  = snowflake_legacy_service_user.legacy_service_users[each.key].name
}
