#!/bin/bash
set -eu
THIS="$(readlink -f "$0")"
THISDIR="$(dirname "${THIS}")"
SRCDIR="$(dirname "${THISDIR}")"
VERSION="$(cat "${SRCDIR}/VERSION")"
UNCOMPRESSED_PLACEHOLDER="@SIZE@"

################################################################################

# Take makeself options, generate a predefined archive, print --info to stdout.
#
# $@ : makeself options
haveInfo() (
    cd "${SRCDIR}" || return 1
    mkdir -p infotest
    ./makeself.sh "$@" ./infotest ./infotest.run infotest ls -lah >/dev/null 2>&1
    assertEquals "$?" 0 >&2
    ./infotest.run --info
    assertEquals "$?" 0 >&2
    rm -rf infotest infotest.run
)

# Read want.info from stdin. Generate have.info using given options. Invoke
# diff want.info have.info and return its exit status
#
# $@ : makeself options
diffInfo() {
    local rc=""
    cd "$(mktemp -d)" || return 1
    cat >want.info
    haveInfo "$@" | sed 's/^Uncompressed size: .*/Uncompressed size: '"${UNCOMPRESSED_PLACEHOLDER}"'/' >have.info
    if diff want.info have.info >&2; then
        rc="$?"
    else
        rc="$?"
    fi
    rm -f have.info want.info
    return "${rc}"
}

sslDiffInfo() {
    if ! command -v openssl >/dev/null 2>&1; then
        # Skip gracefully if openssl is not available
        return 0
    fi
    diffInfo "$@"
}

base64DiffInfo() {
    if ! command -v base64 >/dev/null 2>&1; then
        # Skip gracefully if base64 is not available
        return 0
    fi
    diffInfo "$@"
}

gpgDiffInfo() {
    if ! command -v gpg >/dev/null 2>&1; then
        # Skip gracefully if gpg is not available
        return 0
    fi
    local rc=""
    local gnupg=""
    gnupg="$(mktemp -d)"
    GNUPGHOME="${gnupg}" diffInfo "$@"
    rc="$?"
    rm -rf "${gnupg}"
    return "${rc}"
}

testDefault() (
    cd "$(mktemp -d)" || return 1
    diffInfo --packaging-date "@0" <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: gzip
Encryption: n
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testNocomp() (
    cd "$(mktemp -d)" || return 1
    diffInfo --packaging-date "@0" --nocomp <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: none
Encryption: n
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--nocomp" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testNotemp() (
    cd "$(mktemp -d)" || return 1
    diffInfo --packaging-date "@0" --notemp <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: gzip
Encryption: n
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--notemp" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
directory infotest is permanent
EOF
    assertEquals "$?" 0
)

testSignMasksPassphrase() (
    cd "$(mktemp -d)" || return 1
    diffInfo --packaging-date "@0" --sign "topsecret" <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: gzip
Encryption: n
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--sign" \\
    "XXXX" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testSslEncryptWithCompression() (
    cd "$(mktemp -d)" || return 1
    sslDiffInfo --packaging-date "@0" --ssl-encrypt --ssl-passwd "secret" <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: gzip
Encryption: openssl
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--ssl-encrypt" \\
    "--ssl-passwd" \\
    "secret" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testSslEncryptWithZstdCompression() (
    cd "$(mktemp -d)" || return 1
    if ! command -v zstd >/dev/null 2>&1; then
        return 0
    fi
    sslDiffInfo --packaging-date "@0" --ssl-encrypt --ssl-passwd "secret" --zstd <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: zstd
Encryption: openssl
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--ssl-encrypt" \\
    "--ssl-passwd" \\
    "secret" \\
    "--zstd" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testGpgEncryptWithGzipCompression() (
    cd "$(mktemp -d)" || return 1
    gpgDiffInfo --packaging-date "@0" --gpg-encrypt --gpg-extra "--batch --yes --pinentry-mode=loopback --passphrase=secret" <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: gzip
Encryption: gpg
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--gpg-encrypt" \\
    "--gpg-extra" \\
    "--batch --yes --pinentry-mode=loopback --passphrase=secret" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testGpgEncryptWithZstdCompression() (
    cd "$(mktemp -d)" || return 1
    if ! command -v zstd >/dev/null 2>&1; then
        return 0
    fi
    gpgDiffInfo --packaging-date "@0" --gpg-encrypt --gpg-extra "--batch --yes --pinentry-mode=loopback --passphrase=secret" --zstd <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: zstd
Encryption: gpg
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--gpg-encrypt" \\
    "--gpg-extra" \\
    "--batch --yes --pinentry-mode=loopback --passphrase=secret" \\
    "--zstd" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testBase64WithGzipCompression() (
    cd "$(mktemp -d)" || return 1
    base64DiffInfo --packaging-date "@0" --base64 <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: gzip
Encryption: base64
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--base64" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

testBase64WithZstdCompression() (
    cd "$(mktemp -d)" || return 1
    if ! command -v zstd >/dev/null 2>&1; then
        return 0
    fi
    base64DiffInfo --packaging-date "@0" --base64 --zstd <<EOF
Identification: infotest
Target directory: infotest
Uncompressed size: ${UNCOMPRESSED_PLACEHOLDER}
Compression: zstd
Encryption: base64
Date of packaging: @0
Built with Makeself version ${VERSION}
Build command was: ./makeself.sh \\
    "--packaging-date" \\
    "@0" \\
    "--base64" \\
    "--zstd" \\
    "./infotest" \\
    "./infotest.run" \\
    "infotest" \\
    "ls" \\
    "-lah"
Script run after extraction:
     ls -lah
infotest will be removed after extraction
EOF
    assertEquals "$?" 0
)

################################################################################

# Load and run shUnit2.
source "./shunit2/shunit2"
