#!/bin/sh

# Install a luacoolprop.tds.zip into an isolated TEXMF tree and verify every
# supported TeX frontend.  The working directory and resolver variables point
# outside the repository so a missing archive member cannot be hidden by a
# source-tree file.

set -eu

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

need_command()
{
    command -v "$1" >/dev/null 2>&1 \
        || fail "required command not found: $1"
}

[ "$#" -eq 1 ] || fail "usage: $0 /path/to/luacoolprop.tds.zip"
[ -n "${LUACOOLPROP_LIB:-}" ] \
    || fail "LUACOOLPROP_LIB must point to the CoolProp shared library"
[ -f "$LUACOOLPROP_LIB" ] \
    || fail "CoolProp library not found: $LUACOOLPROP_LIB"

need_command awk
need_command context
need_command cp
need_command dirname
need_command grep
need_command kpsewhich
need_command lualatex
need_command luatex
need_command mkdir
need_command mktemp
need_command rm
need_command tail
need_command unzip

SCRIPT_DIR=$(CDPATH= cd -P "$(dirname "$0")" && pwd) \
    || fail "could not determine the script directory"
PROJECT_DIR=$(CDPATH= cd -P "$SCRIPT_DIR/.." && pwd) \
    || fail "could not determine the project directory"
ARCHIVE_DIR=$(CDPATH= cd -P "$(dirname "$1")" && pwd) \
    || fail "could not resolve the archive directory"
ARCHIVE=$ARCHIVE_DIR/${1##*/}
[ -f "$ARCHIVE" ] || fail "TDS archive not found: $ARCHIVE"
[ "${ARCHIVE##*/}" = luacoolprop.tds.zip ] \
    || fail "the TDS archive must be named luacoolprop.tds.zip"

TEMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/luacoolprop-tds-test.XXXXXX") \
    || fail "could not create a temporary directory"
cleanup()
{
    if [ "${LUACOOLPROP_KEEP_TDS_TEST:-0}" = 1 ]; then
        printf 'Kept installed-tree test directory: %s\n' "$TEMP_DIR" >&2
    else
        rm -rf "$TEMP_DIR"
    fi
}
trap cleanup 0
trap 'exit 1' HUP INT TERM

TEXMF_TREE=$TEMP_DIR/texmf
WORK_DIR=$TEMP_DIR/work
LOG_DIR=$TEMP_DIR/logs
mkdir -p "$TEXMF_TREE" "$WORK_DIR" "$LOG_DIR" \
    || fail "could not create installed-tree test directories"
TEXMF_TREE=$(CDPATH= cd -P "$TEXMF_TREE" && pwd) \
    || fail "could not canonicalize the temporary TEXMF tree"
WORK_DIR=$(CDPATH= cd -P "$WORK_DIR" && pwd) \
    || fail "could not canonicalize the temporary working directory"
unzip -q "$ARCHIVE" -d "$TEXMF_TREE" \
    || fail "could not install the TDS archive"

for installed_file in \
    tex/generic/luacoolprop/luacoolprop.tex \
    tex/generic/luacoolprop/pgflibrarypgfplots.autonode.code.tex \
    tex/latex/luacoolprop/luacoolprop.sty \
    tex/plain/luacoolprop/p-luacoolprop.tex \
    tex/context/third/luacoolprop/t-luacoolprop.tex \
    tex/luatex/luacoolprop/luacoolprop.lua \
    tex/luatex/luacoolprop/pgfplots-autonode.lua \
    doc/generic/luacoolprop/luacoolprop-manual.pdf; do
    [ -f "$TEXMF_TREE/$installed_file" ] \
        || fail "missing TDS member: $installed_file"
done

for fixture in latex plain context autonode autonode-missing-hook; do
    cp "$PROJECT_DIR/tests/tds/$fixture.tex" "$WORK_DIR/$fixture.tex" \
        || fail "could not stage $fixture.tex"
done

TEXMFHOME=$TEXMF_TREE
TEXMFCACHE=$TEMP_DIR/cache
export TEXMFHOME TEXMFCACHE LUACOOLPROP_LIB
unset TEXINPUTS LUAINPUTS TEXMFVAR TEXMFCONFIG
mkdir -p "$TEXMFCACHE"

resolved=$(CDPATH= cd -P "$WORK_DIR" && kpsewhich luacoolprop.sty) \
    || fail "kpathsea did not find installed luacoolprop.sty"
case $resolved in
    "$TEXMF_TREE"/*) ;;
    *) fail "luacoolprop.sty resolved outside the installed TDS tree: $resolved" ;;
esac

run_test()
{
    name=$1
    shift
    log=$LOG_DIR/$name.log
    if (CDPATH= cd -P "$WORK_DIR" && "$@") >"$log" 2>&1; then
        :
    else
        printf 'error: installed-tree %s test failed (log: %s)\n' \
            "$name" "$log" >&2
        tail -n 20 "$log" >&2
        return 1
    fi
    if [ ! -f "$WORK_DIR/$name.pdf" ]; then
        tail -n 20 "$log" >&2
        fail "installed-tree $name test produced no PDF"
    fi
    if grep -F "$PROJECT_DIR/" "$log" >/dev/null 2>&1; then
        fail "installed-tree $name test resolved a runtime file from the repository"
    fi
    if [ "$name" = context ] && grep -E \
        '^(tex error[[:space:]]*>|mtx-context[[:space:]]*> fatal error:)' \
        "$log" >/dev/null 2>&1; then
        fail "installed-tree context test reported a fatal TeX diagnostic"
    fi
    if grep -F 'pgfplots-autonode warning:' "$log" >/dev/null 2>&1; then
        fail "installed-tree $name test reported an autonode warning"
    fi
    if grep -F 'auto node debug=summary' "$WORK_DIR/$name.tex" \
        >/dev/null 2>&1; then
        grep -E 'pgfplots-autonode: solve: [1-9][0-9]* label' \
            "$log" >/dev/null 2>&1 \
            || fail "installed-tree $name test did not run the autonode solve hook"
        grep -F 'pgfplots-autonode: final status:' "$log" >/dev/null 2>&1 \
            || fail "installed-tree $name test has no autonode final status"
    fi
    if [ "$name" = autonode ]; then
        solve_count=$(awk '/pgfplots-autonode: solve:/ { count++ }
          END { print count + 0 }' "$log")
        [ "$solve_count" -eq 2 ] \
            || fail "installed-tree autonode test expected two isolated axis solves (got $solve_count)"
    fi
}

run_missing_hook_test()
{
    log=$LOG_DIR/autonode-missing-hook.log
    if (CDPATH= cd -P "$WORK_DIR" && lualatex --shell-escape \
        --interaction=nonstopmode --halt-on-error --file-line-error \
        autonode-missing-hook.tex) >"$log" 2>&1; then
        :
    else
        printf 'error: installed-tree missing-hook test failed (log: %s)\n' \
            "$log" >&2
        tail -n 20 "$log" >&2
        return 1
    fi
    missing_hook_count=$(awk '
      /label registered without/ { count++ }
      END { print count + 0 }
    ' "$log")
    [ "$missing_hook_count" -eq 1 ] \
        || fail "installed-tree missing-hook test expected one warning (got $missing_hook_count)"
}

run_test latex lualatex --shell-escape --interaction=nonstopmode \
    --halt-on-error --file-line-error latex.tex
run_test plain luatex --shell-escape --interaction=nonstopmode \
    --halt-on-error --file-line-error plain.tex
run_test autonode lualatex --shell-escape --interaction=nonstopmode \
    --halt-on-error --file-line-error autonode.tex
run_missing_hook_test

# ConTeXt uses its own resolver cache. An explicit path list points at the
# installed TDS subtrees without rebuilding or modifying the user's cache.
# The log check above still rejects any runtime file resolved from the checkout.
CONTEXT_PATHS=$TEXMF_TREE/tex/context/third/luacoolprop,$TEXMF_TREE/tex/generic/luacoolprop,$TEXMF_TREE/tex/luatex/luacoolprop
unset TEXMFCACHE
run_test context context --luatex --once --batchmode --shell-escape \
    --path="$CONTEXT_PATHS" --result=context context.tex

printf 'Installed TDS tree passed LuaLaTeX, plain LuaTeX, ConTeXt MkIV, and autonode tests.\n'
