#! /bin/sh

## Launch Calabash, setting up the classpath and support for EXPath Packaging.
## 
## If you installed the full EXPath Repo distribution, including Saxon and
## Calabash themselves, it will find them automatically from the install dir.
## If you want to use your own Calabash and/or Saxon install, just set the
## environment variables CALABASH_HOME and/or SAXON_HOME.  Generally speaking,
## you can set the following environment variables to customize the behaviour
## of this script:
## 
## CALABASH_HOME        the home dir of the Calabash install; must contain a
##                      file named calabash.jar
## 
## CALABASH_JAR         alternatively, instead of CALABASH_HOME, you can
##                      directly set the JAR file path
## 
## SAXON_HOME           the home dir of the Saxon install; must contain a file
##                      named saxon9ee.jar, saxon9pe.jar or saxon9he.jar (if
##                      several exist, it will pick them in that order)
## 
## CALABASH_MAIN        the name of the Java class to use as the main driver;
##                      the default value com.xmlcalabash.drivers.Main is the
##                      official Calabash main, but if you have your own class
##                      you can override it here
## 
## XCC_JAR              the paths to the JAR files for resp. the MarkLogic XCC
## TAGSOUP_JAR          lib, the TagSoup lib, and the isorelax and jing JAR
## ISORELAX_JAR         for Jing
## JING_JAR             
## 
## SLF4J_API_JAR        the paths to the JAR files for logging support
## LOG4J_API_JAR
## LOG4J_CORE_JAR
## LOG4J_SLF4J_JAR
## 
## EXPATH_PKG_REPO_JAR      the paths to the JAR files for Packaging support
## EXPATH_PKG_SAXON_JAR     (resp. the on-disk repo manager, the support for
## EXPATH_PKG_CALABASH_JAR  Saxon, and the support for Calabash)


# ==================== utilities ====================

die() {
    echo
    echo "*** $@" 1>&2;
    exit 1;
}

resolve () {
    if echo "$1" | grep -- '^~' >/dev/null 2>&1; then
        echo "$HOME"`echo $1 | sed s/^~//`;
    else
        echo "$1"
    fi
}

# TODO: Get more options from the saxon script (--repo, --java, --cp, etc.)
usage () {
    echo
    echo "Usage: calabash <script options> <processor options>"
    echo
    echo "Processor options are any option accepted by the original command-line"
    echo "Calabash frontend.  Script options are (all are optional, those marked with"
    echo "an * are repeatable, those with ... require a parameter):"
    echo
    echo "  ++help                    display this help message"
    echo "  ++repo ...                the path to the packaging repository to use"
    echo "  ++java ... *              add an option to the Java Virtual Machine"
    echo "  ++add-cp ... *            add an entry to the classpath"
    echo
}

# ==================== variables ====================

# get the install dir
# TODO: Ask IzPack for substituing it directly at install time...?
INSTALL_DIR=`dirname $0`/..
if test \! -d "$INSTALL_DIR"; then
    die "INTERNAL ERROR: The install directory is not a directory?!? ($INSTALL_DIR)"
fi

# Calabash home
if test -z "$CALABASH_HOME"; then
    # By default, try calabash/ as CALABASH_HOME in the install dir
    if test -d "$INSTALL_DIR/calabash"; then
        CALABASH_HOME="$INSTALL_DIR/calabash"
    else
        die "CALABASH_HOME not set, and $INSTALL_DIR/calabash/ does not exist!"
    fi
fi
# Calabash JAR and main class
if test -z "$CALABASH_JAR"; then
    CALABASH_JAR="${CALABASH_HOME}/calabash.jar"
fi
if test -z "$CALABASH_MAIN"; then
    CALABASH_MAIN=com.xmlcalabash.drivers.Main
fi

# Saxon home
if test -z "$SAXON_HOME"; then
    # By default, try saxon/ as SAXON_HOME in the install dir
    if test -d "$INSTALL_DIR/saxon"; then
        SAXON_HOME="$INSTALL_DIR/saxon"
    else
        die "SAXON_HOME not set, and $INSTALL_DIR/saxon/ does not exist!"
    fi
fi
# Saxon JAR
if test -f "${SAXON_HOME}/saxon9ee.jar"; then
    SAXON_JAR="${SAXON_HOME}/saxon9ee.jar";
elif test -f "${SAXON_HOME}/saxon9pe.jar"; then
    SAXON_JAR="${SAXON_HOME}/saxon9pe.jar";
elif test -f "${SAXON_HOME}/saxon9he.jar"; then
    SAXON_JAR="${SAXON_HOME}/saxon9he.jar";
else
    die "Saxon 9.2+ JAR cannot be found in SAXON_HOME: $SAXON_HOME"
fi

# Libraries
if test -z "$CODEC_JAR"; then
    if test -f "${CALABASH_HOME}/lib/commons-codec-1.6.jar"; then
        CODEC_JAR="${CALABASH_HOME}/lib/commons-codec-1.6.jar"
    fi
fi
if test -z "$LOGGING_JAR"; then
    if test -f "${CALABASH_HOME}/lib/commons-logging-1.1.1.jar"; then
        LOGGING_JAR="${CALABASH_HOME}/lib/commons-logging-1.1.1.jar"
    fi
fi
if test -z "$HTTP_CLIENT_JAR"; then
    if test -f "${CALABASH_HOME}/lib/httpclient-4.2.5.jar"; then
        HTTP_CLIENT_JAR="${CALABASH_HOME}/lib/httpclient-4.2.5.jar"
    fi
fi
if test -z "$HTTP_CORE_JAR"; then
    if test -f "${CALABASH_HOME}/lib/httpcore-4.2.4.jar"; then
        HTTP_CORE_JAR="${CALABASH_HOME}/lib/httpcore-4.2.4.jar"
    fi
fi
if test -z "$HTTP_MIME_JAR"; then
    if test -f "${CALABASH_HOME}/lib/httpmime-4.2.5.jar"; then
        HTTP_MIME_JAR="${CALABASH_HOME}/lib/httpmime-4.2.5.jar"
    fi
fi
if test -z "$IO_JAR"; then
    if test -f "${CALABASH_HOME}/lib/commons-io-2.1.jar"; then
        IO_JAR="${CALABASH_HOME}/lib/commons-io-2.1.jar"
    fi
fi
if test -z "$XCC_JAR"; then
    if test -f "${CALABASH_HOME}/lib/xcc.jar"; then
        XCC_JAR="${CALABASH_HOME}/lib/xcc.jar"
    fi
fi
if test -z "$TAGSOUP_JAR"; then
    if test -f "${CALABASH_HOME}/lib/tagsoup-1.2.jar"; then
        TAGSOUP_JAR="${CALABASH_HOME}/lib/tagsoup-1.2.jar"
    fi
fi
if test -z "$ISORELAX_JAR"; then
    if test -f "${CALABASH_HOME}/lib/isorelax.jar"; then
        ISORELAX_JAR="${CALABASH_HOME}/lib/isorelax.jar"
    fi
fi
if test -z "$JING_JAR"; then
    if test -f "${CALABASH_HOME}/lib/jing.jar"; then
        JING_JAR="${CALABASH_HOME}/lib/jing.jar"
    fi
fi
if test -z "$SLF4J_API_JAR"; then
    if test -f "${CALABASH_HOME}/lib/slf4j-api-1.7.7.jar"; then
        SLF4J_API_JAR="${CALABASH_HOME}/lib/slf4j-api-1.7.7.jar"
    fi
fi
if test -z "$LOG4J_API_JAR"; then
    if test -f "${CALABASH_HOME}/lib/log4j-api-2.0.2.jar"; then
        LOG4J_API_JAR="${CALABASH_HOME}/lib/log4j-api-2.0.2.jar"
    fi
fi
if test -z "$LOG4J_CORE_JAR"; then
    if test -f "${CALABASH_HOME}/lib/log4j-core-2.0.2.jar"; then
        LOG4J_CORE_JAR="${CALABASH_HOME}/lib/log4j-core-2.0.2.jar"
    fi
fi
if test -z "$LOG4J_SLF4J_JAR"; then
    if test -f "${CALABASH_HOME}/lib/log4j-slf4j-impl-2.0.2.jar"; then
        LOG4J_SLF4J_JAR="${CALABASH_HOME}/lib/log4j-slf4j-impl-2.0.2.jar"
    fi
fi

# The EXPath JAR files for packaging support
# tools-java.jar
if test -z "$EXPATH_TOOLS_JAVA_JAR"; then
    EXPATH_TOOLS_JAVA_JAR="$INSTALL_DIR/expath/tools-java.jar"
fi
if test \! -f "$EXPATH_TOOLS_JAVA_JAR"; then
    die "\$EXPATH_TOOLS_JAVA_JAR does not exist: $EXPATH_TOOLS_JAVA_JAR"
fi
# tools-saxon.jar
if test -z "$EXPATH_TOOLS_SAXON_JAR"; then
    EXPATH_TOOLS_SAXON_JAR="$INSTALL_DIR/expath/tools-saxon.jar"
fi
if test \! -f "$EXPATH_TOOLS_SAXON_JAR"; then
    die "\$EXPATH_TOOLS_SAXON_JAR does not exist: $EXPATH_TOOLS_SAXON_JAR"
fi
# pkg-java.jar
if test -z "$EXPATH_PKG_REPO_JAR"; then
    EXPATH_PKG_REPO_JAR="$INSTALL_DIR/expath/pkg-java.jar"
fi
if test \! -f "$EXPATH_PKG_REPO_JAR"; then
    die "\$EXPATH_PKG_REPO_JAR does not exist: $EXPATH_PKG_REPO_JAR"
fi
# pkg-saxon.jar
if test -z "$EXPATH_PKG_SAXON_JAR"; then
    EXPATH_PKG_SAXON_JAR="$INSTALL_DIR/expath/pkg-saxon.jar"
fi
if test \! -f "$EXPATH_PKG_SAXON_JAR"; then
    die "\$EXPATH_PKG_SAXON_JAR does not exist: $EXPATH_PKG_SAXON_JAR"
fi
# pkg-calabash.jar
if test -z "$EXPATH_PKG_CALABASH_JAR"; then
    EXPATH_PKG_CALABASH_JAR="$INSTALL_DIR/expath/pkg-calabash.jar"
fi
if test \! -f "$EXPATH_PKG_CALABASH_JAR"; then
    die "\$EXPATH_PKG_CALABASH_JAR does not exist: $EXPATH_PKG_CALABASH_JAR"
fi

# The classpath delimiter
if uname | grep -i cygwin >/dev/null 2>&1; then
    CP_DELIM=";"
else
    CP_DELIM=":"
fi

CP=
JAVA_OPT=
REPO=$EXPATH_REPO

# ================= the initial classpath =================

CP="${CALABASH_JAR}"
CP="${CP}${CP_DELIM}${SAXON_JAR}"
CP="${CP}${CP_DELIM}${CODEC_JAR}"
CP="${CP}${CP_DELIM}${LOGGING_JAR}"
CP="${CP}${CP_DELIM}${HTTP_CLIENT_JAR}"
CP="${CP}${CP_DELIM}${HTTP_CORE_JAR}"
CP="${CP}${CP_DELIM}${HTTP_MIME_JAR}"
CP="${CP}${CP_DELIM}${IO_JAR}"
CP="${CP}${CP_DELIM}${XCC_JAR}"
CP="${CP}${CP_DELIM}${TAGSOUP_JAR}"
CP="${CP}${CP_DELIM}${ISORELAX_JAR}"
CP="${CP}${CP_DELIM}${JING_JAR}"
CP="${CP}${CP_DELIM}${SLF4J_API_JAR}"
CP="${CP}${CP_DELIM}${LOG4J_API_JAR}"
CP="${CP}${CP_DELIM}${LOG4J_CORE_JAR}"
CP="${CP}${CP_DELIM}${LOG4J_SLF4J_JAR}"
CP="${CP}${CP_DELIM}${EXPATH_TOOLS_JAVA_JAR}"
CP="${CP}${CP_DELIM}${EXPATH_TOOLS_SAXON_JAR}"
CP="${CP}${CP_DELIM}${EXPATH_PKG_REPO_JAR}"
CP="${CP}${CP_DELIM}${EXPATH_PKG_SAXON_JAR}"
CP="${CP}${CP_DELIM}${EXPATH_PKG_CALABASH_JAR}"

# ==================== the options ====================

while echo "$1" | grep ^++ >/dev/null 2>&1 && test "$1" != ++; do
    case "$1" in
        # Add some path to the class path.  May be repeated.
        ++add-cp)
            shift
            ADD_CP="${ADD_CP}${CP_DELIM}`resolve $1`";;
        # The EXPath Packaging repository
        ++repo)
            shift
            REPO=$1;;
        # Additional option for the JVM
        ++java)
            shift
            JAVA_OPT="$JAVA_OPT $1";;
        # Help message
        ++help)
            usage
            exit 0;;
        # Unknown option!
        ++*)
            die "Unknown option: $1"
    esac
    shift;
done

# ==================== EXPath repo ====================

if test -n "$REPO"; then

    # the repo itself
    JAVA_OPT="$JAVA_OPT -Dorg.expath.pkg.calabash.repo=$REPO"

    # add each line of {repo}/*/.calabash/classpath.txt to the classpath
    # TODO: Shouldn't we add the extensions for Saxon as well...?
    oldIFS=$IFS
    IFS=$'\n'
    for cp in `resolve "${REPO}"`/*/.calabash/classpath.txt
    do
        # If no file corresponds to the glob, the glob is returned as
        # is.  We check this is not the case by looking for '*' in the
        # path (in this case we want to iterate zero times).
        if echo "$cp" | grep '*' >/dev/null; then
            true; #nothing
        else
            for jar in `cat "$cp"`
            do
                ADD_CP="${ADD_CP}${CP_DELIM}${jar}";
            done
        fi
    done
    IFS=$oldIFS

fi

# ==================== do it! ====================

# The complete classpath, with additional entries
CP="${CP}${ADD_CP}"

#    -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog \
#    -Dorg.apache.commons.logging.simplelog.showdatetime=true \
#    -Dorg.apache.commons.logging.simplelog.log.org=TRACE \
#    -Djava.util.logging.config.file=/Users/fgeorges/logging.properties \

# Do it
java \
    $JAVA_OPT \
    -ea -esa \
    -Dcom.xmlcalabash.xproc-configurer=org.expath.pkg.calabash.PkgConfigurer \
    -cp "$CP" \
    $CALABASH_MAIN "$@"
