#!/usr/bin/env bash
set -Eeuo pipefail
umask 077

trace() {
  printf '__TRACE__ stage=%s\n' "$1"
}

fact() {
  printf '__FACT__ %s=%s\n' "$1" "$2"
}

block() {
  echo "__BLOCK_BEGIN__ $1"
  printf '%s\n' "$2"
  echo "__BLOCK_END__ $1"
}

die() {
  local code="$1"
  shift

  printf '__ERROR__ code=%s message=%s\n' \
    "$code" \
    "$*"

  exit "$code"
}

trace docker_inventory

command -v docker >/dev/null 2>&1 ||
  die 21 "docker_command_missing"

DOCKER_PS="$(
  docker ps \
    --format '{{.Names}}\t{{.Image}}\t{{.Status}}'
)"

block docker_ps "$DOCKER_PS"

mapfile -t RUNNING_CONTAINERS < <(
  docker ps --format '{{.Names}}'
)

[ "${#RUNNING_CONTAINERS[@]}" -gt 0 ] ||
  die 22 "no_running_containers"

trace postgres_candidate_discovery

declare -a CANDIDATES=()

for container in "${RUNNING_CONTAINERS[@]}"; do
  ENVIRONMENT="$(
    docker inspect \
      --format '{{range .Config.Env}}{{println .}}{{end}}' \
      "$container"
  )"

  IMAGE="$(
    docker inspect \
      --format '{{.Config.Image}}' \
      "$container"
  )"

  HAS_PSQL=false

  if docker exec "$container" \
    sh -lc 'command -v psql >/dev/null 2>&1'
  then
    HAS_PSQL=true
  fi

  HAS_POSTGRES_ENV=false

  if grep -Eq \
    '^(POSTGRES_USER|POSTGRES_DB)=' \
    <<< "$ENVIRONMENT"
  then
    HAS_POSTGRES_ENV=true
  fi

  fact "container.${container}.image" "$IMAGE"
  fact "container.${container}.has_psql" "$HAS_PSQL"
  fact "container.${container}.has_postgres_env" "$HAS_POSTGRES_ENV"

  if [ "$HAS_PSQL" = true ] &&
     [ "$HAS_POSTGRES_ENV" = true ]
  then
    CANDIDATES+=("$container")
  fi
done

fact postgres_candidate_count "${#CANDIDATES[@]}"

[ "${#CANDIDATES[@]}" -ge 1 ] ||
  die 23 "postgres_candidate_not_found"

PG_CONTAINER=""

for candidate in "${CANDIDATES[@]}"; do
  if [ "$candidate" = "wgaccess-postgres" ]; then
    PG_CONTAINER="$candidate"
    break
  fi
done

if [ -z "$PG_CONTAINER" ]; then
  for candidate in "${CANDIDATES[@]}"; do
    case "$candidate" in
      *postgres*)
        PG_CONTAINER="$candidate"
        break
        ;;
    esac
  done
fi

if [ -z "$PG_CONTAINER" ]; then
  PG_CONTAINER="${CANDIDATES[0]}"
fi

fact postgres_container "$PG_CONTAINER"

trace postgres_environment

PG_ENV="$(
  docker inspect \
    --format '{{range .Config.Env}}{{println .}}{{end}}' \
    "$PG_CONTAINER"
)"

PGUSER_VALUE="$(
  sed -n 's/^POSTGRES_USER=//p' <<< "$PG_ENV" |
    head -n1
)"

PGDATABASE_VALUE="$(
  sed -n 's/^POSTGRES_DB=//p' <<< "$PG_ENV" |
    head -n1
)"

[ -n "$PGUSER_VALUE" ] ||
  PGUSER_VALUE="postgres"

[ -n "$PGDATABASE_VALUE" ] ||
  PGDATABASE_VALUE="$PGUSER_VALUE"

fact postgres_user "$PGUSER_VALUE"
fact postgres_database "$PGDATABASE_VALUE"

psql_query() {
  docker exec "$PG_CONTAINER" \
    psql \
      -X \
      -v ON_ERROR_STOP=1 \
      -U "$PGUSER_VALUE" \
      -d "$PGDATABASE_VALUE" \
      -Atqc "$1"
}

trace database_ping

DB_PING="$(psql_query 'SELECT 1;')"

[ "$DB_PING" = "1" ] ||
  die 24 "database_ping_failed_result=$DB_PING"

fact database_ping "$DB_PING"

trace schema_inventory

PUBLIC_TABLES="$(
  psql_query "
    SELECT tablename
    FROM pg_tables
    WHERE schemaname='public'
    ORDER BY tablename;
  "
)"

block public_tables "$PUBLIC_TABLES"

table_exists() {
  local table="$1"

  psql_query "
    SELECT CASE
      WHEN to_regclass('public.${table}') IS NULL
      THEN 'false'
      ELSE 'true'
    END;
  "
}

PEERS_EXISTS="$(table_exists peers)"
LEASES_EXISTS="$(table_exists peer_egress_leases)"
JOBS_EXISTS="$(table_exists jobs)"

fact table.peers.exists "$PEERS_EXISTS"
fact table.peer_egress_leases.exists "$LEASES_EXISTS"
fact table.jobs.exists "$JOBS_EXISTS"

[ "$PEERS_EXISTS" = true ] ||
  die 25 "peers_table_missing"

[ "$LEASES_EXISTS" = true ] ||
  die 26 "peer_egress_leases_table_missing"

[ "$JOBS_EXISTS" = true ] ||
  die 27 "jobs_table_missing"

trace schema_columns

PEERS_COLUMNS="$(
  psql_query "
    SELECT column_name
    FROM information_schema.columns
    WHERE table_schema='public'
      AND table_name='peers'
    ORDER BY ordinal_position;
  "
)"

LEASES_COLUMNS="$(
  psql_query "
    SELECT column_name
    FROM information_schema.columns
    WHERE table_schema='public'
      AND table_name='peer_egress_leases'
    ORDER BY ordinal_position;
  "
)"

JOBS_COLUMNS="$(
  psql_query "
    SELECT column_name
    FROM information_schema.columns
    WHERE table_schema='public'
      AND table_name='jobs'
    ORDER BY ordinal_position;
  "
)"

block peers_columns "$PEERS_COLUMNS"
block peer_egress_leases_columns "$LEASES_COLUMNS"
block jobs_columns "$JOBS_COLUMNS"

grep -Fxq enabled <<< "$PEERS_COLUMNS" ||
  die 28 "peers_enabled_column_missing"

grep -Fxq status <<< "$JOBS_COLUMNS" ||
  die 29 "jobs_status_column_missing"

trace canonical_counts

ENABLED_PEERS="$(
  psql_query "
    SELECT count(*)
    FROM peers
    WHERE enabled IS TRUE;
  "
)"

LEASE_ROWS="$(
  psql_query "
    SELECT count(*)
    FROM peer_egress_leases;
  "
)"

PENDING_JOBS="$(
  psql_query "
    SELECT count(*)
    FROM jobs
    WHERE status='pending';
  "
)"

fact enabled_peers "$ENABLED_PEERS"
fact lease_rows "$LEASE_ROWS"
fact pending_jobs "$PENDING_JOBS"

trace related_existing_tools

RELATED_TOOLS="$(
  {
    find /opt/wg-access \
      -maxdepth 4 \
      -type f \
      \( \
        -name '*.sh' \
        -o -name 'docker-compose*.yml' \
        -o -name 'docker-compose*.yaml' \
        -o -name '.env' \
      \) \
      -print 2>/dev/null ||
      true

    find /usr/local/sbin \
      -maxdepth 1 \
      -type f \
      -name '*wg-access*' \
      -print 2>/dev/null ||
      true
  } |
    sort
)"

block related_tools "$RELATED_TOOLS"

fact related_tool_count "$(
  sed '/^$/d' <<< "$RELATED_TOOLS" |
    wc -l |
    tr -d ' '
)"

trace complete
