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/delphi/human_users/terraform.tfstate"
    region  = "us-east-1"
    encrypt = "true"
  }
}

resource "snowflake_user" "users" {
  for_each = var.users

  name         = each.key
  login_name   = each.value.email
  first_name   = each.value.first_name
  last_name    = each.value.last_name
  display_name = "${each.value.first_name} ${each.value.last_name}" != " " ? "${each.value.first_name} ${each.value.last_name}" : null
  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_secondary_roles_option = each.value.default_secondary_roles_option

  rsa_public_key   = each.value.rsa_public_key
  rsa_public_key_2 = each.value.rsa_public_key_2

  lifecycle {
    ignore_changes = [
      show_output,
      must_change_password,
      password,
      default_warehouse,
      default_role,
      default_namespace,
      mins_to_bypass_mfa,
      mins_to_unlock,
      disable_mfa,
      statement_timeout_in_seconds,
      parameters,
      display_name,
      binary_input_format,
      client_session_keep_alive,
      enable_unredacted_query_syntax_error,
      timezone
    ]
  }
}

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

  on {
    object_type = "USER"
    object_name = snowflake_user.users[each.key].name
  }
}

locals {

  user_roles = { for user, props in var.users :
    user => props.roles
  }

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

  users_by_team = {
    for team in distinct([for u in var.users : u.team if u.team != ""]) :
    team => [for username, user in var.users : username if user.team == team]
  }
}

resource "snowflake_grant_account_role" "role_grants" {
  for_each  = local.role_grants
  role_name = each.value.role
  user_name = snowflake_user.users[each.value.user].name
}

resource "snowflake_user_authentication_policy_attachment" "users" {
  for_each                   = var.users
  provider                   = snowflake.prod_atlantis
  authentication_policy_name = "\"SNOWFLAKE_SETTINGS\".\"AUTHENTICATION_POLICIES\".\"${each.value.authentication_policy}\""
  user_name                  = snowflake_user.users[each.key].name
}

# assign team tag
resource "snowflake_tag_association" "team_user_associations" {
  for_each = local.users_by_team

  provider           = snowflake.prod_atlantis
  object_identifiers = each.value # list of usernames
  object_type        = "USER"
  tag_id             = "SNOWFLAKE_SETTINGS.TAGS.TEAM"
  tag_value          = each.key # team name

  depends_on = [snowflake_user.users]
}

