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/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   = coalesce(each.value.login, 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
  rsa_public_key_2 = each.value.rsa_public_key_2

  statement_timeout_in_seconds = each.value.statement_timeout_in_seconds

  lifecycle {
    ignore_changes = [
      mins_to_unlock,
      parameters,
      show_output,
      binary_input_format,
      display_name,
      client_session_keep_alive,
    ]
  }
}

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   = coalesce(each.value.login, 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
  rsa_public_key_2 = each.value.rsa_public_key_2

  statement_timeout_in_seconds = each.value.statement_timeout_in_seconds

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

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 }
  }]...)

  users_by_team = {
    for team in distinct([for u in var.service_users : u.team if u.team != ""]) :
    team => [for username, user in var.service_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 = 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
}

# assign team tag
resource "snowflake_tag_association" "team_user_association" {
  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
}
