#!/bin/sh
# Run process, pipeline and interactive job-control regressions.
set -eu
cd "$(dirname "$0")/.."

if [ ! -x ./cclsh ]; then
    echo "cclsh integration: build ./cclsh first with scripts/build" >&2
    exit 2
fi
if [ ! -s ./cclsh.image ]; then
    echo "cclsh integration: ./cclsh.image is missing; run scripts/build" >&2
    exit 2
fi

for program in script setsid timeout pkill ps tr grep stty seq yes head wc cat sleep printf rev realpath
do
    if ! command -v "$program" >/dev/null 2>&1; then
        echo "cclsh integration: required program not found: $program" >&2
        exit 2
    fi
done

if find source cclsh.asd dependencies.lock -type f -newer ./cclsh.image \
        -print -quit | grep -q .
then
    echo "cclsh integration: ./cclsh.image is stale; run scripts/build first" >&2
    exit 2
fi

locked_dependency_commit()
{
    dependency_name=$1
    dependency_prefix=$dependency_name=
    dependency_commit=
    dependency_count=0
    while IFS= read -r dependency_line || [ -n "$dependency_line" ]; do
        case "$dependency_line" in
            "$dependency_prefix"*)
                dependency_commit=${dependency_line#"$dependency_prefix"}
                dependency_count=$((dependency_count + 1))
                ;;
        esac
    done <dependencies.lock
    if [ "$dependency_count" -ne 1 ] ||
       [ "${#dependency_commit}" -ne 40 ]
    then
        return 1
    fi
    case "$dependency_commit" in
        *[!0123456789abcdef]*) return 1 ;;
    esac
    printf '%s\n' "$dependency_commit"
}
if ! expected_clinedi_commit=$(locked_dependency_commit clinedi) ||
   ! expected_structlisp_commit=$(locked_dependency_commit structlisp) ||
   ! expected_cl_colorist_commit=$(locked_dependency_commit cl-colorist) ||
   ! expected_colorlisp_commit=$(locked_dependency_commit colorlisp) ||
   ! expected_colordiff_commit=$(locked_dependency_commit colordiff)
then
    echo "cclsh integration: dependencies.lock is invalid" >&2
    exit 2
fi
if ! CCLSH_SAFE=1 \
     CCLSH_EXPECTED_CLINEDI_COMMIT="$expected_clinedi_commit" \
     CCLSH_EXPECTED_STRUCTLISP_COMMIT="$expected_structlisp_commit" \
     CCLSH_EXPECTED_CL_COLORIST_COMMIT="$expected_cl_colorist_commit" \
     CCLSH_EXPECTED_COLORLISP_COMMIT="$expected_colorlisp_commit" \
     CCLSH_EXPECTED_COLORDIFF_COMMIT="$expected_colordiff_commit" \
     ./cclsh -c \
     '(unless
          (and
           (string=
            cclsh:*cclsh-build-clinedi-commit*
            (cclsh:getenv "CCLSH_EXPECTED_CLINEDI_COMMIT"))
           (string=
            cclsh:*cclsh-build-structlisp-commit*
            (cclsh:getenv "CCLSH_EXPECTED_STRUCTLISP_COMMIT"))
           (string=
            cclsh:*cclsh-build-cl-colorist-commit*
            (cclsh:getenv "CCLSH_EXPECTED_CL_COLORIST_COMMIT"))
           (string=
            cclsh:*cclsh-build-colorlisp-commit*
            (cclsh:getenv "CCLSH_EXPECTED_COLORLISP_COMMIT"))
           (string=
            cclsh:*cclsh-build-colordiff-commit*
            (cclsh:getenv "CCLSH_EXPECTED_COLORDIFF_COMMIT")))
        (error "saved image has stale dependency revisions"))' \
     >/dev/null 2>&1
then
    echo "cclsh integration: ./cclsh.image has stale dependencies; run scripts/build first" >&2
    exit 2
fi

ccl_command=${CCLSH_CCL:-ccl}
if ! command -v "$ccl_command" >/dev/null 2>&1; then
    echo "cclsh integration: CCL executable not found: $ccl_command" >&2
    exit 1
fi
CCLSH_TEST_CCL=$(realpath -e "$(command -v "$ccl_command")")
export CCLSH_TEST_CCL
set -- -n -b
if [ -n "${CCLSH_CCL_IMAGE:-}" ]; then
    CCLSH_TEST_CCL_IMAGE=$(realpath -e "$CCLSH_CCL_IMAGE")
    export CCLSH_TEST_CCL_IMAGE
    set -- -I "$CCLSH_CCL_IMAGE" "$@"
fi
"$ccl_command" "$@" \
    -e '(setf ccl:*default-file-character-encoding* :utf-8)' \
    -e \
    '(handler-case
         (load "tests/integration.lisp" :external-format :utf-8)
       (serious-condition (condition)
         (format *error-output*
                 "cclsh integration loader failed: ~a~%" condition)
         (ccl:quit 1)))'

tests/installed-image.sh
tests/fast-launcher.sh
