#!/usr/bin/env bash

dump_baron_postgres() {
  local backup_dir="$1"
  local db_user="${DB_USER:-baron}"
  local db_password="${DB_PASSWORD:-password}"
  local db_name="${DB_NAME:-baron_sso}"

  backup_require_command docker
  backup_require_container baron_postgres
  mkdir -p "$backup_dir/postgres" "$backup_dir/reports"

  backup_log "Dumping Baron Postgres database: $db_name"
  docker exec -e "PGPASSWORD=$db_password" baron_postgres \
    pg_dump -U "$db_user" -d "$db_name" -Fc >"$backup_dir/postgres/baron.dump"

  docker exec -e "PGPASSWORD=$db_password" baron_postgres \
    psql -U "$db_user" -d "$db_name" -Atc "select schemaname || '.' || relname || ':' || (xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', schemaname, relname), false, true, '')))[1]::text from pg_stat_user_tables order by 1" \
    >"$backup_dir/reports/baron-postgres-row-counts.txt"

  docker exec -e "PGPASSWORD=$db_password" baron_postgres \
    psql -U "$db_user" -d "$db_name" -Atc "select 'public.rp_user_metadata:' || count(*) from public.rp_user_metadata union all select 'public.users.global_custom_claims:' || count(*) from public.users where metadata ? 'global_custom_claims' union all select 'public.users.global_custom_claim_types:' || count(*) from public.users where metadata ? 'global_custom_claim_types' order by 1" \
    >"$backup_dir/reports/baron-postgres-custom-claim-counts.txt"
}

dump_ory_postgres() {
  local backup_dir="$1"
  local db_user="${ORY_POSTGRES_USER:-ory}"
  local db_password="${ORY_POSTGRES_PASSWORD:-secret}"
  local kratos_db="${KRATOS_DB:-ory_kratos}"
  local hydra_db="${HYDRA_DB:-ory_hydra}"
  local keto_db="${KETO_DB:-ory_keto}"
  local db_name

  backup_require_command docker
  backup_require_container ory_postgres
  mkdir -p "$backup_dir/postgres" "$backup_dir/reports"

  backup_log "Dumping Ory Postgres globals"
  docker exec -e "PGPASSWORD=$db_password" ory_postgres \
    pg_dumpall -U "$db_user" --globals-only >"$backup_dir/postgres/globals.sql"

  for db_name in "$kratos_db" "$hydra_db" "$keto_db"; do
    backup_log "Dumping Ory Postgres database: $db_name"
    docker exec -e "PGPASSWORD=$db_password" ory_postgres \
      pg_dump -U "$db_user" -d "$db_name" -Fc >"$backup_dir/postgres/${db_name}.dump"
    docker exec -e "PGPASSWORD=$db_password" ory_postgres \
      psql -U "$db_user" -d "$db_name" -Atc "select schemaname || '.' || relname || ':' || (xpath('/row/c/text()', query_to_xml(format('select count(*) as c from %I.%I', schemaname, relname), false, true, '')))[1]::text from pg_stat_user_tables order by 1" \
      >"$backup_dir/reports/${db_name}-row-counts.txt"
  done
}

restore_baron_postgres() {
  local backup_dir="$1"
  local db_user="${DB_USER:-baron}"
  local db_password="${DB_PASSWORD:-password}"
  local db_name="${DB_NAME:-baron_sso}"

  backup_require_path "$backup_dir/postgres/baron.dump"
  backup_require_command docker
  backup_require_container baron_postgres

  backup_log "Restoring Baron Postgres database: $db_name"
  docker exec -i -e "PGPASSWORD=$db_password" baron_postgres \
    pg_restore -U "$db_user" -d "$db_name" --clean --if-exists <"$backup_dir/postgres/baron.dump"
}

restore_ory_postgres() {
  local backup_dir="$1"
  local db_user="${ORY_POSTGRES_USER:-ory}"
  local db_password="${ORY_POSTGRES_PASSWORD:-secret}"
  local kratos_db="${KRATOS_DB:-ory_kratos}"
  local hydra_db="${HYDRA_DB:-ory_hydra}"
  local keto_db="${KETO_DB:-ory_keto}"
  local db_name

  backup_require_command docker
  backup_require_container ory_postgres

  for db_name in "$kratos_db" "$hydra_db" "$keto_db"; do
    backup_require_path "$backup_dir/postgres/${db_name}.dump"
    backup_log "Restoring Ory Postgres database: $db_name"
    docker exec -i -e "PGPASSWORD=$db_password" ory_postgres \
      pg_restore -U "$db_user" -d "$db_name" --clean --if-exists <"$backup_dir/postgres/${db_name}.dump"
  done
}

postgres_target_has_data() {
  local container="$1"
  local user="$2"
  local password="$3"
  local database="$4"

  backup_require_command docker
  backup_require_container "$container"
  docker exec -e "PGPASSWORD=$password" "$container" \
    psql -U "$user" -d "$database" -Atc "select exists (select 1 from pg_tables where schemaname not in ('pg_catalog','information_schema') limit 1)" \
    2>/dev/null | grep -qx 't'
}
