#!/usr/bin/env bash
# Copyright (c) 2018-2019 The University of Sheffield.
#               2019-2020 The University of Exeter. 
#               2018-2020 The University of Paris-Saclay. 
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# SPDX-License-Identifier: BSD-2-Clause

#set -e
shopt -s nocasematch

# get global configuration  
if [ -d .git ]; then
    export `git show -s --format="COMMIT=%H DATE=%cd" --date=short | sed -e 's|-|/|g'`
fi    
source .config

print_help()
{
    echo "Usage: install [OPTION] "
    echo ""
    echo "Run ..."
    echo ""
    echo "  --help, -h                display this help message"
    echo "  --isabelle, -i isabelle   isabelle command used for installation"
    echo "                            (default: $ISABELLE)"
    echo "  --skip-patch-and-afp, -s  skip installation of Isabelle/DOF patch for" 
    echo "                            Isabelle and required AFP entries. "
    echo "                            USE AT YOUR OWN RISK (default: $SKIP)"
}



exit_error() {
    echo ""
    echo "  *** Isabelle/DOF installation FAILED, please check the README.md for help ***"
    echo ""
    exit 1
}

check_isabelle_version() {
    echo "* Checking Isabelle version:"
    if [ "$ISABELLE_VERSION" != "$ACTUAL_ISABELLE_VERSION" ]; then
        echo "  WARNING:"
        echo "    The version of Isabelle (i.e., $ACTUAL_ISABELLE_VERSION) you are using"
        echo "                        IS NOT SUPPORTED"
        echo "    by the current version of Isabelle/DOF. Please install a supported"
        echo "    version of Isabelle and rerun the install script, providing the"
        echo "    the \"isabelle\" command as argument."
        echo "    Isabelle ($ISABELLE_VERSION) can be obtained from:"
        echo "    $ISABELLE_URL"
        echo 
        read -p "    Still continue (y/N)? " -n 1 -r
        echo 
        if [[ $REPLY =~ ^[Yy]$ ]];
        then 
            echo "    Continuing installation on your OWN risk."
        else
            exit_error
        fi
     else
        echo "  Success: found supported Isabelle version ($ISABELLE_VERSION)"
    fi
}

check_pdftex() {
    echo "* Checking (La)TeX installation:"
    OLDDIR=`pwd`
    DIR=`mktemp -d`
    cd $DIR; 
    pdftex -interaction=nonstopmode \\expanded{Success}\\end > /dev/null
    if [ $? -eq 0 ]; then
        echo "  Success: pdftex supports \\expanded{} primitive."
    else 
        cd $OLDDIR
        echo "  WARNING:"
        echo "    The version of pdf(La)TeX you are using is outdated (and does"
        echo "    not support the \\expanded primitive). It is not supported by the"
        echo "    current version of Isabelle/DOF. Please install a supported TeX"
        echo "    distribution (e.g., TeXLive 2020 or later)."
        echo 
        read -p "    Still continue (y/N)? " -n 1 -r
        echo 
        if [[ $REPLY =~ ^[Yy]$ ]];
        then 
            echo "    Continuing installation on your OWN risk."
        else
            exit_error
        fi
    fi
    cd $OLDDIR
}

check_afp_entries() {
    echo "* Checking availability of AFP entries:"
    missing=""
    required="Regular-Sets Functional-Automata"
    for afp in $required; do 
        res=`$ISABELLE build -n $afp 2>/dev/null || true`
        if [ "$res" != "" ]; then 
            echo "  Success: found APF entry $afp."
        else
            echo "  Warning: could not find AFP entry $afp."
            missing="$missing $afp"
       fi
    done
    if [ "$missing" != "" ]; then 
        echo "           Trying to install AFP (this might take a few *minutes*) ...."
	extract=""
	for e in $missing; do
	    extract="$extract $AFP_DATE/thys/$e"
	done
	mkdir -p .afp
        if curl -s -L $AFP_URL | tar zxf - -C .afp $extract; then 
            for e in $missing; do 
                echo "           Registering $e in $ISABELLE_HOME_USER/ROOTS"
		touch $ISABELLE_HOME_USER/ROOTS
		grep -q $PWD/.afp/$AFP_DATE/thys/$e $ISABELLE_HOME_USER/ROOTS || echo "$PWD/.afp/$AFP_DATE/thys/$e" >> $ISABELLE_HOME_USER/ROOTS 
            done
            echo "           AFP installation successful."
        else
            echo "  FAILURE: could not find AFP entries: $missing."
            echo "    Please obtain the AFP from"
            echo "    $AFP_URL"
            echo "    and follow the following instructions:"
            echo "    https://www.isa-afp.org/using.html"
            exit_error
        fi
    fi
}

check_isa_dof_patch() {
    echo "* Check availability of Isabelle/DOF patch:"
    src="src/patches/thy_output.ML"
    dst="$ISABELLE_HOME/src/Pure/Thy/thy_output.ML"
     
    if command -v cmp > /dev/null 2>&1 && cmp -s "$src" "$dst" ; then
        echo "  Success: latest Isabelle/DOF patch already applied"
        if isabelle process -e 'Thy_Output.set_meta_args_parser' &> /dev/null ; then
            true
        else
            echo "  Warning: Isabelle/HOL needs to be rebuild to activate patch."
        fi
    else
        command -v cmp >/dev/null 2>&1 || echo "  Warning: cmp not available, cannot check if patch is already applied."
        echo "  Warning: Isabelle/DOF patch is not available or outdated."
        echo "           Trying to patch system ...."
        if [ ! -f "$dst.backup-by-isadof-installer" ]; then
            cp -f "$dst" "$dst.backup-by-isadof-installer" || true;
        fi
	if (cp -f $src $dst) &> /dev/null; then 
	    echo "       Applied patch successfully, Isabelle/HOL will be rebuilt during"
	    echo "       the next start of Isabelle."
	else
            echo "  FAILURE: Could not apply Isabelle/DOF patch."
            echo "    Please copy $src to $dst, e.g.:"
            echo "       cp -f $src $dst"
            echo "    and rebuild Isabelle/HOL."
            exit_error
	fi
    fi
}

check_old_installation(){
    echo "* Searching for existing installation:"
    if [[ -d "$ISABELLE_HOME_USER/DOF" ]]; then
        echo "  Found old installation, moving it to $ISABELLE_HOME_USER/DOF.bak."
        rm -rf "$ISABELLE_HOME_USER/DOF.bak"
        mv "$ISABELLE_HOME_USER/DOF" "$ISABELLE_HOME_USER/DOF.bak"
    else
        echo "  No old installation found."
    fi

}

install_and_register(){
    echo "* Installing Isabelle/DOF"

    DIR="$ISABELLE_HOME_USER/DOF/Tools"
    echo "  - Installing Tools in $DIR"
    mkdir -p "$DIR"
    cp $GEN_DIR/Tools/* "$DIR"
    chmod 755 "$DIR"/*

    DIR="$ISABELLE_HOME_USER/DOF/document-template"
    echo "  - Installing document templates in $DIR"
    mkdir -p "$DIR"
    cp $GEN_DIR/scripts/* "$DIR"
    cp $GEN_DIR/document-templates/* "$DIR"
    cp $GEN_DIR/DOF/*/*.sty "$DIR"
    
    ISABELLE_SHORT_VERSION=`echo $ISABELLE_VERSION | sed -e 's/:.*$//'`
    sed -i -e "s|%%% CONFIG %%%| \
      \\\\renewcommand{\\\\dof@isabelleversion}{$ISABELLE_SHORT_VERSION} \
      \\\\renewcommand{\\\\isabellelatestversion}{$DOF_LATEST_ISABELLE} \
      \\\\renewcommand{\\\\isabellefullversion}{$ISABELLE_VERSION\\\\xspace} \
      \\\\renewcommand{\\\\dof@version}{$DOF_VERSION} \
      \\\\renewcommand{\\\\doflatestversion}{$DOF_LATEST_VERSION} \
      \\\\renewcommand{\\\\isadoflatestdoi}{$DOF_LATEST_DOI} \
      \\\\renewcommand{\\\\isadofgenericdoi}{$DOF_GENERIC_DOI} \
      \\\\renewcommand{\\\\isabelleurl}{$ISABELLE_URL} \
      \\\\renewcommand{\\\\dofurl}{$DOF_URL} \
      \\\\renewcommand{\\\\dof@artifacturl}{https://$DOF_ARTIFACT_HOST/$DOF_ARTIFACT_DIR}|" \
      "$DIR/DOF-core.sty"

    DIR="$ISABELLE_HOME_USER/DOF/latex"
    echo "  - Installing LaTeX styles in $DIR"
    mkdir -p "$DIR"
    cp $GEN_DIR/ontologies/*/*.sty "$DIR"
    
    DIR="$ISABELLE_HOME_USER/etc"
    echo "  - Registering Isabelle/DOF"
    mkdir -p "$DIR"
    if [[ $ISABELLE_TOOLS = *DOF* ]]; then
        echo "    * Tools already registered in $DIR/settings"
    else
        echo "    * Registering tools in $DIR/settings"
        echo 'ISABELLE_TOOLS=$ISABELLE_TOOLS:$ISABELLE_HOME_USER/DOF/Tools' \
             >> "$DIR/settings"
    fi
    if [[ $ISABELLE_DOCS = *DOF* ]]; then
        echo "    * Docs already registered in $DIR/settings"
    else
        echo "    * Registering docs in $DIR/settings"
        echo "ISABELLE_DOCS=$PWD/doc"':$ISABELLE_DOCS' \
             >> "$DIR/settings"
    fi
    sed -i -e "s|<isadofurl>|$DOF_URL|" $ISABELLE_HOME_USER/DOF/*/*
    LTX_VERSION="$DATE $DOF_VERSION/$ISABELLE_SHORT_VERSION"
    sed -i -e "s|<isadofltxversion>|$LTX_VERSION|" $ISABELLE_HOME_USER/DOF/*/*
    touch $ISABELLE_HOME_USER/ROOTS
    grep -q $PWD'$' $ISABELLE_HOME_USER/ROOTS || echo "$PWD" >> $ISABELLE_HOME_USER/ROOTS 
}


ISABELLE=`which isabelle`
SKIP="false"
while [ $# -gt 0 ]
do
    case "$1" in
        --isabelle|-i)
            ISABELLE="$2";
            shift;;
        --skip-patch-and-afp|-s)
            SKIP="true";;
        --help|-h)
            print_help
            exit 0;;
        *)  print_help
            exit 1;;
    esac
    shift
done


ACTUAL_ISABELLE_VERSION=`$ISABELLE version`
GEN_DIR=src
PROG=`echo $0 | sed 's|.*/||'`;
VARS=`$ISABELLE getenv ISABELLE_HOME_USER ISABELLE_HOME ISABELLE_TOOLS ISABELLE_DOCS`
for i in $VARS; do 
	export "$i"
done

echo ""
echo "Isabelle/DOF Installer"
echo "======================"
check_isabelle_version
check_pdftex
if [ "$SKIP" = "true" ]; then
  echo "* Warning: skipping installation of Isabelle patch and AFP entries."
else
  check_isa_dof_patch
  check_afp_entries
fi
check_old_installation
install_and_register
echo "* Installation successful. Enjoy Isabelle/DOF, you can build the session"
echo "  Isabelle/DOF and all example documents by executing:"
echo "  $ISABELLE build -D ."
exit 0
