#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

fail() {
  echo "FAIL: $*" >&2
  exit 1
}

assert_file_contains() {
  local file="$1"
  local pattern="$2"
  grep -qE "$pattern" "$file" || fail "$file does not contain pattern: $pattern"
}

assert_file_not_contains() {
  local file="$1"
  local pattern="$2"
  if grep -qE "$pattern" "$file"; then
    fail "$file contains forbidden pattern: $pattern"
  fi
}

assert_bash_syntax() {
  local file="$1"
  bash -n "$file" || fail "$file has invalid bash syntax"
}

assert_archive_clean_for_linux_tar() {
  local archive="$1"
  local metadata_entries
  local xattr_entries

  metadata_entries="$(tar -tzf "$archive" | grep -E '(^|/)\._|(^|/)\.DS_Store$|(^|/)__MACOSX(/|$)' || true)"
  if [[ -n "$metadata_entries" ]]; then
    fail "$archive contains macOS metadata files"
  fi

  xattr_entries="$(gzip -dc "$archive" | strings | grep -E 'LIBARCHIVE\.xattr|SCHILY\.xattr|com\.apple' || true)"
  if [[ -n "$xattr_entries" ]]; then
    fail "$archive contains macOS extended attributes"
  fi
}

assert_bash_syntax "$ROOT_DIR/dapostinstall.sh"
assert_bash_syntax "$ROOT_DIR/da_cli.sh"
assert_bash_syntax "$ROOT_DIR/daupdate.sh"

php -l "$ROOT_DIR/lang_pl.php" >/dev/null || fail "lang_pl.php has invalid PHP syntax"
assert_archive_clean_for_linux_tar "$ROOT_DIR/spolszczenie_enhanced.tar.gz"

assert_file_contains "$ROOT_DIR/da_cli.sh" '^DEFAULTPACKAGE=NO-LIMIT$'
assert_file_not_contains "$ROOT_DIR/da_cli.sh" '^eparated list of IP addresses$'

assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'c\\ns1='
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'c\\ns2='
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns1"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns2"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^DEFAULT_NS1=dns3\.hitme\.net\.pl$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^DEFAULT_NS2=dns4\.hitme\.net\.pl$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^php1_release='
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^php2_release='
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^php9_release='
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^ioncube=yes$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^zend=yes$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^opcache=yes$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^imap=yes$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^imagick=yes$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^SETUP_TXT="\$DADIR/conf/setup\.txt"$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^update_daupdate_tools\(\) \{$'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '/opt/daupdate\.sh update'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'require_file "\$SETUP_TXT"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'DA_ADMINPASS=\$\(get_key_value "\$SETUP_TXT" "adminpass"\)'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns1" "\$DEFAULT_NS1"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'set_key_value "\$DADIR/conf/directadmin\.conf" "ns2" "\$DEFAULT_NS2"'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'MIN_PASSWORD_LENGTH'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'MAX_PASSWORD_LENGTH'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'ITERATION_LIMIT'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '/dev/urandom'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'changeuserpass admin'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" '^configure_custombuild_php\(\) \{$'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'release_var="php\$\{idx\}_release"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'release="\$\{!release_var\}"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build set "php\$\{idx\}_release" "\$release"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build set "php\$\{idx\}_mode" "php-fpm"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build php'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build rewrite_confs'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'eximconf_release'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '\./build'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '^[[:space:]]*\$CBDIR/build'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build set eximconf yes'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'da build exim_conf'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$ioncube" "ioncube" "ioncube"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$zend" "zend" "zend"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$opcache" "opcache" "opcache"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$imap" "php_imap" "php_imap"'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'build_php_extension "\$imagick" "imagick" "imagick"'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'sed -i .*imagick=no'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'sed -i .*imap=no'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" "sed -i 's/DA_.*mail_powitalny.txt"
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'mv mail_powitalny.txt /root'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'DA_PHP_LIST=\$\(get_php_release_list "\$DA_OPTIONSCONF"\)'
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'render_template "\$DAPOSTINSTALL_DIR/mail_powitalny.txt" "/root/mail_powitalny.txt"'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'PS3='
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '^select opt in'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" '"Niestandardowa"\)'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Czy instalowac'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Czy aktywowac'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Podaj adres NS'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Jaka skorke ustawic'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" 'Wybierz tryb instalacji'
assert_file_not_contains "$ROOT_DIR/dapostinstall.sh" "s/evolution/enhanced"
assert_file_contains "$ROOT_DIR/dapostinstall.sh" 'Skorka evolution zostala ustawiona jako domyslna'
assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_HOSTNAME\}\}'
assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_HASLO\}\}'
assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_PHP_LIST\}\}'
assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_NS1\}\}'
assert_file_contains "$ROOT_DIR/mail_powitalny.txt" '\{\{DA_NS2\}\}'
assert_file_not_contains "$ROOT_DIR/mail_powitalny.txt" 'DA_PHP1'

COMMON_SH="$ROOT_DIR/lib/common.sh"
[[ -f "$COMMON_SH" ]] || fail "missing lib/common.sh"

# shellcheck source=/dev/null
source "$COMMON_SH"

tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT

kv_file="$tmp_dir/example.conf"
printf 'ns1=old.example\nother=value\n' > "$kv_file"
set_key_value "$kv_file" "ns1" "dns3.hitme.net.pl"
set_key_value "$kv_file" "ns2" "dns4.hitme.net.pl"

grep -qx 'ns1=dns3.hitme.net.pl' "$kv_file" || fail "set_key_value did not replace ns1"
grep -qx 'ns2=dns4.hitme.net.pl' "$kv_file" || fail "set_key_value did not append ns2"
[[ "$(grep -c '^ns1=' "$kv_file")" -eq 1 ]] || fail "set_key_value duplicated ns1"

setup_file="$tmp_dir/setup.txt"
printf 'hostname=server.example\nadminpass=hG7KZfTPq1z8f4KC3N5J4\n' > "$setup_file"
[[ "$(get_key_value "$setup_file" "adminpass")" == "hG7KZfTPq1z8f4KC3N5J4" ]] || fail "get_key_value did not read adminpass"

php_options="$tmp_dir/options.conf"
printf 'php1_release=8.3\nphp2_release=8.2\nphp3_release=no\nphp9_release=7.4\n' > "$php_options"
expected_php=$'PHP 8.3 (domyślna)\nPHP 8.2\nPHP 7.4'
[[ "$(get_php_release_list "$php_options")" == "$expected_php" ]] || fail "get_php_release_list returned unexpected output"

php1_release=8.3
php2_release=8.2
php3_release=8.1
php4_release=7.4
php5_release=no
php6_release=no
php7_release=no
php8_release=no
php9_release=5.6
php_commands="$tmp_dir/php_commands.log"
for idx in 1 2 3 4 5 6 7 8 9; do
  release_var="php${idx}_release"
  release="${!release_var}"
  printf 'da build set php%s_release %s\n' "$idx" "$release" >> "$php_commands"
done
grep -qx 'da build set php1_release 8.3' "$php_commands" || fail "php1_release command is wrong"
grep -qx 'da build set php2_release 8.2' "$php_commands" || fail "php2_release command is wrong"
grep -qx 'da build set php9_release 5.6' "$php_commands" || fail "php9_release command is wrong"
[[ "$(cut -d' ' -f5 "$php_commands" | sort -u | wc -l | tr -d ' ')" -gt 2 ]] || fail "php release commands appear to reuse a single value"

template_file="$tmp_dir/template.txt"
output_file="$tmp_dir/output.txt"
printf 'Host: {{DA_HOSTNAME}}\nPass: {{DA_HASLO}}\nPHP:\n{{DA_PHP_LIST}}\n' > "$template_file"
export DA_HOSTNAME='server.example'
export DA_HASLO='abc/123&xyz'
export DA_PHP_LIST="$expected_php"
render_template "$template_file" "$output_file"
grep -qx 'Host: server.example' "$output_file" || fail "render_template did not replace hostname"
grep -qx 'Pass: abc/123&xyz' "$output_file" || fail "render_template did not safely replace password"
grep -qx 'PHP 8.3 (domyślna)' "$output_file" || fail "render_template did not replace multiline PHP list"

echo "quality checks passed"
