#!/usr/bin/env bash
set -u

project_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
test_count=0
failure_count=0
contract_variables=(
  SITE_URL
  LOCAL_SITE_URL
  WP_LOCAL_DB_NAME
  WP_LOCAL_DB_USER
  WP_LOCAL_DB_PASSWORD
  WP_LOCAL_DB_ROOT_PASSWORD
  WP_REST_USER
  WP_REST_APPLICATION_PASSWORD
  WP_SSH_HOST
  WP_SSH_PORT
  WP_SSH_USER
  WP_SSH_KEY_PATH
  WP_SSH_KNOWN_HOSTS_PATH
  WP_REMOTE_PATH
  WP_DB_HOST
  WP_DB_PORT
  WP_DB_NAME
  WP_DB_USER
  WP_DB_PASSWORD
  WP_DB_SSL_MODE
  WP_DB_SSL_CA
)

fail() {
  printf '%s\n' "$*" >&2
  exit 1
}

assert_status() {
  local expected="$1"
  local actual="$2"

  [[ "$actual" -eq "$expected" ]] ||
    fail "Expected status ${expected}. Actual status: ${actual}."
}

assert_contains() {
  local content="$1"
  local expected="$2"

  [[ "$content" == *"$expected"* ]] ||
    fail "Expected output to contain: ${expected}"
}

assert_not_contains() {
  local content="$1"
  local rejected="$2"

  [[ "$content" != *"$rejected"* ]] ||
    fail "Expected output not to contain: ${rejected}"
}

assert_file_contains_line() {
  local file="$1"
  local expected="$2"

  grep -Fx -- "$expected" "$file" >/dev/null ||
    fail "Expected ${file} to contain this argument: ${expected}"
}

assert_file_does_not_exist() {
  local file="$1"

  [[ ! -e "$file" ]] || fail "Expected no command invocation at: ${file}"
}

assert_file_starts_with_lines() {
  local file="$1"
  shift
  local expected actual line_count
  line_count="$#"
  printf -v expected '%s\n' "$@"
  actual="$(head -n "$line_count" "$file")"

  [[ "$actual"$'\n' == "$expected" ]] ||
    fail "Expected ${file} to start with the required arguments."
}

run_test() {
  local name="$1"
  local function_name="$2"

  test_count=$((test_count + 1))
  if ("$function_name"); then
    printf 'ok %s - %s\n' "$test_count" "$name"
  else
    failure_count=$((failure_count + 1))
    printf 'not ok %s - %s\n' "$test_count" "$name"
  fi
}

run_and_capture() {
  local output_file="$1"
  shift

  set +e
  "$@" >"$output_file" 2>&1
  local command_status=$?
  set -e
  return "$command_status"
}

with_empty_environment() {
  env -i PATH="$PATH" "$@"
}

make_command_stubs() {
  local stub_directory="$1"

  mkdir -p "$stub_directory"
  cat >"$stub_directory/ssh" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$@" >"${SSH_CAPTURE_FILE:?}"
EOF
  cat >"$stub_directory/mysql" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$@" >"${MYSQL_CAPTURE_FILE:?}"
printf '%s' "${MYSQL_PWD-}" >"${MYSQL_PASSWORD_CAPTURE_FILE:?}"
EOF
  chmod +x "$stub_directory/ssh" "$stub_directory/mysql"
}

test_validator_rejects_unknown_mode() {
  local temporary_directory output status
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" "$project_root/scripts/validate-environment.sh" invalid
  status=$?

  assert_status 64 "$status"
  assert_contains "$(cat "$output")" 'Usage:'
}

test_local_validator_reports_each_missing_variable() {
  local temporary_directory output status content variable
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" with_empty_environment \
    "$project_root/scripts/validate-environment.sh" local
  status=$?
  content="$(cat "$output")"

  assert_status 65 "$status"
  for variable in \
    LOCAL_SITE_URL \
    WP_LOCAL_DB_NAME \
    WP_LOCAL_DB_USER \
    WP_LOCAL_DB_PASSWORD \
    WP_LOCAL_DB_ROOT_PASSWORD
  do
    assert_contains "$content" "${variable} is required."
  done
}

test_rest_validator_reports_only_rest_variables() {
  local temporary_directory output status content variable
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" with_empty_environment \
    "$project_root/scripts/validate-environment.sh" rest
  status=$?
  content="$(cat "$output")"

  assert_status 65 "$status"
  for variable in \
    SITE_URL \
    WP_REST_USER \
    WP_REST_APPLICATION_PASSWORD
  do
    assert_contains "$content" "${variable} is required."
  done

  for variable in "${contract_variables[@]}"; do
    case "$variable" in
      SITE_URL|WP_REST_USER|WP_REST_APPLICATION_PASSWORD)
        ;;
      *)
        assert_not_contains "$content" "${variable} is required."
        ;;
    esac
  done
}

test_ssh_validator_reports_only_ssh_variables() {
  local temporary_directory output status content variable
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" with_empty_environment \
    "$project_root/scripts/validate-environment.sh" ssh
  status=$?
  content="$(cat "$output")"

  assert_status 65 "$status"
  for variable in \
    WP_SSH_HOST \
    WP_SSH_PORT \
    WP_SSH_USER \
    WP_SSH_KEY_PATH \
    WP_SSH_KNOWN_HOSTS_PATH \
    WP_REMOTE_PATH
  do
    assert_contains "$content" "${variable} is required."
  done

  for variable in "${contract_variables[@]}"; do
    case "$variable" in
      WP_SSH_HOST|WP_SSH_PORT|WP_SSH_USER|WP_SSH_KEY_PATH|\
        WP_SSH_KNOWN_HOSTS_PATH|WP_REMOTE_PATH)
        ;;
      *)
        assert_not_contains "$content" "${variable} is required."
        ;;
    esac
  done
}

test_database_validator_reports_only_database_variables() {
  local temporary_directory output status content variable
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" with_empty_environment \
    "$project_root/scripts/validate-environment.sh" database
  status=$?
  content="$(cat "$output")"

  assert_status 65 "$status"
  for variable in \
    WP_DB_HOST \
    WP_DB_PORT \
    WP_DB_NAME \
    WP_DB_USER \
    WP_DB_PASSWORD \
    WP_DB_SSL_MODE \
    WP_DB_SSL_CA
  do
    assert_contains "$content" "${variable} is required."
  done

  for variable in "${contract_variables[@]}"; do
    case "$variable" in
      WP_DB_HOST|WP_DB_PORT|WP_DB_NAME|WP_DB_USER|WP_DB_PASSWORD|\
        WP_DB_SSL_MODE|WP_DB_SSL_CA)
        ;;
      *)
        assert_not_contains "$content" "${variable} is required."
        ;;
    esac
  done
}

test_validator_rejects_remote_mode() {
  local temporary_directory output status
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" \
    "$project_root/scripts/validate-environment.sh" remote
  status=$?

  assert_status 64 "$status"
  assert_contains "$(cat "$output")" 'Usage:'
}

test_local_validator_accepts_complete_environment() {
  with_empty_environment \
    LOCAL_SITE_URL=http://localhost:8080 \
    WP_LOCAL_DB_NAME=wordpress \
    WP_LOCAL_DB_USER=wordpress \
    WP_LOCAL_DB_PASSWORD=local-password \
    WP_LOCAL_DB_ROOT_PASSWORD=local-root-password \
    "$project_root/scripts/validate-environment.sh" local
}

test_rest_validator_accepts_complete_environment() {
  with_empty_environment \
    SITE_URL=https://example.test \
    WP_REST_USER=reader \
    WP_REST_APPLICATION_PASSWORD=application-password \
    "$project_root/scripts/validate-environment.sh" rest
}

test_ssh_validator_accepts_complete_environment() {
  with_empty_environment \
    WP_SSH_HOST=example.test \
    WP_SSH_PORT=22 \
    WP_SSH_USER=reader \
    WP_SSH_KEY_PATH=/nonexistent/test-key \
    WP_SSH_KNOWN_HOSTS_PATH=/nonexistent/known-hosts \
    WP_REMOTE_PATH=/srv/wordpress \
    "$project_root/scripts/validate-environment.sh" ssh
}

test_database_validator_accepts_complete_environment() {
  with_empty_environment \
    WP_DB_HOST=db.example.test \
    WP_DB_PORT=3306 \
    WP_DB_NAME=wordpress \
    WP_DB_USER=reader \
    WP_DB_PASSWORD=remote-password \
    WP_DB_SSL_MODE=VERIFY_IDENTITY \
    WP_DB_SSL_CA=/nonexistent/test-ca \
    "$project_root/scripts/validate-environment.sh" database
}

test_environment_loader_exports_known_values_without_execution() {
  local temporary_directory environment_file marker output
  temporary_directory="$(mktemp -d)"
  environment_file="$temporary_directory/environment"
  marker="$temporary_directory/executed"
  output="$temporary_directory/output"

  cat >"$environment_file" <<EOF
LOCAL_SITE_URL=http://localhost:8080
WP_LOCAL_DB_NAME=wordpress
WP_LOCAL_DB_USER=wordpress
WP_LOCAL_DB_PASSWORD=\$(touch ${marker})
WP_LOCAL_DB_ROOT_PASSWORD=local-root-password
EOF

  "$project_root/scripts/with-environment.sh" \
    local \
    "$environment_file" \
    bash -c 'printf "%s" "$WP_LOCAL_DB_PASSWORD"' >"$output"

  [[ "$(cat "$output")" == "\$(touch ${marker})" ]] ||
    fail 'The loader did not preserve the literal value.'
  assert_file_does_not_exist "$marker"
}

test_environment_loader_rejects_unknown_variables() {
  local temporary_directory environment_file output status
  temporary_directory="$(mktemp -d)"
  environment_file="$temporary_directory/environment"
  output="$temporary_directory/output"

  cat >"$environment_file" <<'EOF'
LOCAL_SITE_URL=http://localhost:8080
WP_LOCAL_DB_NAME=wordpress
WP_LOCAL_DB_USER=wordpress
WP_LOCAL_DB_PASSWORD=local-password
WP_LOCAL_DB_ROOT_PASSWORD=local-root-password
UNAPPROVED_VARIABLE=value
EOF

  run_and_capture "$output" \
    "$project_root/scripts/with-environment.sh" \
    local \
    "$environment_file" \
    true
  status=$?

  assert_status 65 "$status"
  assert_contains "$(cat "$output")" \
    'UNAPPROVED_VARIABLE is not in the environment contract.'
}

test_environment_loader_clears_ambient_contract_values() {
  local temporary_directory environment_file child_capture output status
  local ambient_environment=()
  local variable
  temporary_directory="$(mktemp -d)"
  environment_file="$temporary_directory/environment"
  child_capture="$temporary_directory/child-environment"
  output="$temporary_directory/output"
  : >"$environment_file"

  for variable in "${contract_variables[@]}"; do
    ambient_environment+=("${variable}=stale-${variable}")
  done

  run_and_capture "$output" env "${ambient_environment[@]}" \
    "$project_root/scripts/with-environment.sh" \
    local \
    "$environment_file" \
    bash -c 'env >"$1"' _ "$child_capture"
  status=$?

  assert_status 65 "$status"
  assert_contains "$(cat "$output")" 'LOCAL_SITE_URL is required.'
  assert_file_does_not_exist "$child_capture"
}

test_environment_loader_replaces_ambient_values_and_limits_child_scope() {
  local temporary_directory environment_file output content
  local ambient_environment=()
  local variable
  temporary_directory="$(mktemp -d)"
  environment_file="$temporary_directory/environment"
  output="$temporary_directory/output"

  cat >"$environment_file" <<'EOF'
SITE_URL=https://reviewed.example.test
LOCAL_SITE_URL=http://localhost:8080
WP_LOCAL_DB_NAME=reviewed-name
WP_LOCAL_DB_USER=reviewed-user
WP_LOCAL_DB_PASSWORD=reviewed-password
WP_LOCAL_DB_ROOT_PASSWORD=reviewed-root-password
EOF

  for variable in "${contract_variables[@]}"; do
    ambient_environment+=("${variable}=stale-${variable}")
  done

  env "${ambient_environment[@]}" \
    "$project_root/scripts/with-environment.sh" \
    local \
    "$environment_file" \
    env >"$output"
  content="$(cat "$output")"

  assert_contains "$content" 'WP_LOCAL_DB_PASSWORD=reviewed-password'
  for variable in "${contract_variables[@]}"; do
    case "$variable" in
      LOCAL_SITE_URL|WP_LOCAL_DB_NAME|WP_LOCAL_DB_USER|\
        WP_LOCAL_DB_PASSWORD|WP_LOCAL_DB_ROOT_PASSWORD)
        ;;
      *)
        if grep -Eq "^${variable}=" "$output"; then
          fail "The local child received ${variable}."
        fi
        ;;
    esac
  done
}

test_public_rest_check_does_not_pass_credentials() {
  local temporary_directory stub_directory arguments_file environment_capture
  temporary_directory="$(mktemp -d)"
  stub_directory="$temporary_directory/bin"
  arguments_file="$temporary_directory/curl-arguments"
  environment_capture="$temporary_directory/curl-environment"
  mkdir -p "$stub_directory"

  cat >"$stub_directory/curl" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$@" >"${CURL_ARGUMENTS_FILE:?}"
env >"${CURL_ENVIRONMENT_FILE:?}"
EOF
  chmod +x "$stub_directory/curl"

  PATH="$stub_directory:$PATH" \
    CURL_ARGUMENTS_FILE="$arguments_file" \
    CURL_ENVIRONMENT_FILE="$environment_capture" \
    SITE_URL=https://phyllisschlafly.com \
    WP_REST_USER=stale-user \
    WP_REST_APPLICATION_PASSWORD=stale-password \
    "$project_root/scripts/rest-public-read.sh"

  assert_file_contains_line "$arguments_file" '--disable'
  assert_file_contains_line "$arguments_file" '--fail'
  assert_file_contains_line "$arguments_file" 'https://phyllisschlafly.com/wp-json/'
  if grep -Eq '^WP_REST_(USER|APPLICATION_PASSWORD)=' "$environment_capture"; then
    fail 'The public REST check passed credential placeholders to curl.'
  fi
}

test_wp_rejects_write_command() {
  local temporary_directory output status
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" "$project_root/scripts/wp-read.sh" plugin install akismet
  status=$?

  assert_status 64 "$status"
  assert_contains "$(cat "$output")" 'Command is not in the read-only allowlist.'
}

test_db_rejects_update() {
  local temporary_directory output status
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" "$project_root/scripts/db-read.sh" \
    "UPDATE wp_options SET option_value='x'"
  status=$?

  assert_status 64 "$status"
  assert_contains "$(cat "$output")" 'Only read-only SQL is allowed.'
}

test_db_rejects_multiple_statements() {
  local temporary_directory output status
  temporary_directory="$(mktemp -d)"
  output="$temporary_directory/output"

  run_and_capture "$output" "$project_root/scripts/db-read.sh" \
    'SELECT 1; DELETE FROM wp_posts'
  status=$?

  assert_status 64 "$status"
  assert_contains "$(cat "$output")" 'Multiple SQL statements are not allowed.'
}

test_db_rejects_comment_bypasses() {
  local sql temporary_directory output status
  temporary_directory="$(mktemp -d)"

  for sql in \
    "SELECT 1 INTO/**/OUTFILE '/tmp/x'" \
    "SELECT 1 INTO/*comment*/DUMPFILE '/tmp/x'" \
    $'SELECT 1 INTO -- comment\nOUTFILE "/tmp/x"' \
    $'SELECT 1 INTO#comment\nOUTFILE "/tmp/x"'
  do
    output="$temporary_directory/output"
    run_and_capture "$output" "$project_root/scripts/db-read.sh" "$sql"
    status=$?
    assert_status 64 "$status"
    assert_contains "$(cat "$output")" 'SQL comments are not allowed.'
  done
}

test_db_rejects_file_writes() {
  local keyword temporary_directory output status
  temporary_directory="$(mktemp -d)"

  for keyword in OUTFILE DUMPFILE; do
    output="$temporary_directory/output"
    run_and_capture "$output" "$project_root/scripts/db-read.sh" \
      "SELECT 'x' INTO ${keyword} '/tmp/x'"
    status=$?
    assert_status 64 "$status"
    assert_contains "$(cat "$output")" 'SQL file writes are not allowed.'
  done
}

test_db_rejects_mysql_client_commands_and_backslash_escapes() {
  local sql temporary_directory stub_directory capture_file output status ca_file
  temporary_directory="$(mktemp -d)"
  stub_directory="$temporary_directory/bin"
  capture_file="$temporary_directory/mysql-arguments"
  output="$temporary_directory/output"
  ca_file="$temporary_directory/ca.pem"
  : >"$ca_file"
  make_command_stubs "$stub_directory"

  for sql in \
    $'SELECT 1\n\\!' \
    $'SELECT 1\n\\.' \
    $'SELECT 1\n\\r' \
    $'SELECT 1\n\\q'
  do
    run_and_capture "$output" env \
      PATH="$stub_directory:$PATH" \
      MYSQL_CAPTURE_FILE="$capture_file" \
      MYSQL_PASSWORD_CAPTURE_FILE="$temporary_directory/mysql-password" \
      WP_DB_HOST=db.example.test \
      WP_DB_PORT=3306 \
      WP_DB_NAME=wordpress \
      WP_DB_USER=reader \
      WP_DB_PASSWORD=password \
      WP_DB_SSL_MODE=VERIFY_IDENTITY \
      WP_DB_SSL_CA="$ca_file" \
      "$project_root/scripts/db-read.sh" "$sql"
    status=$?

    assert_status 64 "$status"
    assert_contains "$(cat "$output")" \
      'MySQL client commands and backslash escapes are not allowed.'
    assert_file_does_not_exist "$capture_file"
  done
}

test_wp_safe_command_uses_ssh_controls_without_connection() {
  local temporary_directory stub_directory capture_file key_file known_hosts_file
  temporary_directory="$(mktemp -d)"
  stub_directory="$temporary_directory/bin"
  capture_file="$temporary_directory/ssh-arguments"
  key_file="$temporary_directory/key"
  known_hosts_file="$temporary_directory/known-hosts"
  : >"$key_file"
  : >"$known_hosts_file"
  make_command_stubs "$stub_directory"

  PATH="$stub_directory:$PATH" \
    SSH_CAPTURE_FILE="$capture_file" \
    WP_SSH_HOST=example.test \
    WP_SSH_PORT=2222 \
    WP_SSH_USER=reader \
    WP_SSH_KEY_PATH="$key_file" \
    WP_SSH_KNOWN_HOSTS_PATH="$known_hosts_file" \
    WP_REMOTE_PATH=/srv/wordpress \
    "$project_root/scripts/wp-read.sh" plugin list

  assert_file_starts_with_lines "$capture_file" '-F' 'none'
  assert_file_contains_line "$capture_file" '-p'
  assert_file_contains_line "$capture_file" '2222'
  assert_file_contains_line "$capture_file" '-i'
  assert_file_contains_line "$capture_file" "$key_file"
  assert_file_contains_line "$capture_file" 'BatchMode=yes'
  assert_file_contains_line "$capture_file" 'IdentitiesOnly=yes'
  assert_file_contains_line "$capture_file" 'PreferredAuthentications=publickey'
  assert_file_contains_line "$capture_file" 'PasswordAuthentication=no'
  assert_file_contains_line "$capture_file" 'KbdInteractiveAuthentication=no'
  assert_file_contains_line "$capture_file" 'ClearAllForwardings=yes'
  assert_file_contains_line "$capture_file" 'ForwardAgent=no'
  assert_file_contains_line "$capture_file" 'PermitLocalCommand=no'
  assert_file_contains_line "$capture_file" 'StrictHostKeyChecking=yes'
  assert_file_contains_line "$capture_file" "UserKnownHostsFile=$known_hosts_file"
}

test_db_requires_verify_identity_before_connection() {
  local temporary_directory stub_directory capture_file output status ca_file
  temporary_directory="$(mktemp -d)"
  stub_directory="$temporary_directory/bin"
  capture_file="$temporary_directory/mysql-arguments"
  output="$temporary_directory/output"
  ca_file="$temporary_directory/ca.pem"
  : >"$ca_file"
  make_command_stubs "$stub_directory"

  run_and_capture "$output" env \
    PATH="$stub_directory:$PATH" \
    MYSQL_CAPTURE_FILE="$capture_file" \
    WP_DB_HOST=db.example.test \
    WP_DB_PORT=3306 \
    WP_DB_NAME=wordpress \
    WP_DB_USER=reader \
    WP_DB_PASSWORD=password \
    WP_DB_SSL_MODE=REQUIRED \
    WP_DB_SSL_CA="$ca_file" \
    "$project_root/scripts/db-read.sh" 'SELECT 1'
  status=$?

  assert_status 65 "$status"
  assert_contains "$(cat "$output")" 'WP_DB_SSL_MODE must be VERIFY_IDENTITY.'
  assert_file_does_not_exist "$capture_file"
}

test_db_requires_readable_ca_before_connection() {
  local temporary_directory stub_directory capture_file output status
  temporary_directory="$(mktemp -d)"
  stub_directory="$temporary_directory/bin"
  capture_file="$temporary_directory/mysql-arguments"
  output="$temporary_directory/output"
  make_command_stubs "$stub_directory"

  run_and_capture "$output" env \
    PATH="$stub_directory:$PATH" \
    MYSQL_CAPTURE_FILE="$capture_file" \
    WP_DB_HOST=db.example.test \
    WP_DB_PORT=3306 \
    WP_DB_NAME=wordpress \
    WP_DB_USER=reader \
    WP_DB_PASSWORD=password \
    WP_DB_SSL_MODE=VERIFY_IDENTITY \
    WP_DB_SSL_CA="$temporary_directory/missing-ca.pem" \
    "$project_root/scripts/db-read.sh" 'SELECT 1'
  status=$?

  assert_status 66 "$status"
  assert_contains "$(cat "$output")" \
    'WP_DB_SSL_CA must identify a readable CA certificate.'
  assert_file_does_not_exist "$capture_file"
}

test_db_safe_command_uses_tls_controls_without_connection() {
  local temporary_directory stub_directory capture_file password_file ca_file
  temporary_directory="$(mktemp -d)"
  stub_directory="$temporary_directory/bin"
  capture_file="$temporary_directory/mysql-arguments"
  password_file="$temporary_directory/mysql-password"
  ca_file="$temporary_directory/ca.pem"
  : >"$ca_file"
  make_command_stubs "$stub_directory"

  PATH="$stub_directory:$PATH" \
    MYSQL_CAPTURE_FILE="$capture_file" \
    MYSQL_PASSWORD_CAPTURE_FILE="$password_file" \
    WP_DB_HOST=db.example.test \
    WP_DB_PORT=3307 \
    WP_DB_NAME=wordpress \
    WP_DB_USER=reader \
    WP_DB_PASSWORD=test-password \
    WP_DB_SSL_MODE=VERIFY_IDENTITY \
    WP_DB_SSL_CA="$ca_file" \
    "$project_root/scripts/db-read.sh" 'SELECT option_name FROM wp_options'

  assert_file_starts_with_lines \
    "$capture_file" \
    '--no-defaults' \
    '--no-login-paths'
  assert_file_contains_line "$capture_file" '--host=db.example.test'
  assert_file_contains_line "$capture_file" '--port=3307'
  assert_file_contains_line "$capture_file" '--user=reader'
  assert_file_contains_line "$capture_file" '--database=wordpress'
  assert_file_contains_line "$capture_file" '--ssl-mode=VERIFY_IDENTITY'
  assert_file_contains_line "$capture_file" "--ssl-ca=$ca_file"
  assert_file_contains_line "$capture_file" '--batch'
  assert_file_contains_line "$capture_file" '--execute=SELECT option_name FROM wp_options'
  [[ "$(cat "$password_file")" == 'test-password' ]] ||
    fail 'Expected mysql to receive the password through MYSQL_PWD.'
}

run_test 'validator rejects an unknown mode' test_validator_rejects_unknown_mode
run_test \
  'local validator reports each missing variable' \
  test_local_validator_reports_each_missing_variable
run_test \
  'REST validator reports only REST variables' \
  test_rest_validator_reports_only_rest_variables
run_test \
  'SSH validator reports only SSH variables' \
  test_ssh_validator_reports_only_ssh_variables
run_test \
  'database validator reports only database variables' \
  test_database_validator_reports_only_database_variables
run_test 'validator rejects remote mode' test_validator_rejects_remote_mode
run_test \
  'local validator accepts a complete environment' \
  test_local_validator_accepts_complete_environment
run_test \
  'REST validator accepts a complete environment' \
  test_rest_validator_accepts_complete_environment
run_test \
  'SSH validator accepts a complete environment' \
  test_ssh_validator_accepts_complete_environment
run_test \
  'database validator accepts a complete environment' \
  test_database_validator_accepts_complete_environment
run_test \
  'environment loader exports known values without execution' \
  test_environment_loader_exports_known_values_without_execution
run_test \
  'environment loader rejects unknown variables' \
  test_environment_loader_rejects_unknown_variables
run_test \
  'environment loader clears ambient contract values' \
  test_environment_loader_clears_ambient_contract_values
run_test \
  'environment loader replaces ambient values and limits child scope' \
  test_environment_loader_replaces_ambient_values_and_limits_child_scope
run_test \
  'public REST check does not pass credentials' \
  test_public_rest_check_does_not_pass_credentials
run_test 'WP guard rejects a write command' test_wp_rejects_write_command
run_test 'database guard rejects UPDATE' test_db_rejects_update
run_test \
  'database guard rejects multiple statements' \
  test_db_rejects_multiple_statements
run_test \
  'database guard rejects comment bypasses' \
  test_db_rejects_comment_bypasses
run_test 'database guard rejects file writes' test_db_rejects_file_writes
run_test \
  'database guard rejects MySQL client commands and backslash escapes' \
  test_db_rejects_mysql_client_commands_and_backslash_escapes
run_test \
  'safe WP command uses SSH controls without a connection' \
  test_wp_safe_command_uses_ssh_controls_without_connection
run_test \
  'database guard requires VERIFY_IDENTITY before a connection' \
  test_db_requires_verify_identity_before_connection
run_test \
  'database guard requires a readable CA before a connection' \
  test_db_requires_readable_ca_before_connection
run_test \
  'safe database command uses TLS controls without a connection' \
  test_db_safe_command_uses_tls_controls_without_connection

if ((failure_count > 0)); then
  printf '%s of %s guard tests failed.\n' "$failure_count" "$test_count" >&2
  exit 1
fi

printf 'All %s guard tests passed.\n' "$test_count"
