#! /bin/sh
## NOAA PMEL TMAP
## Finstall
## Does two things:
## Option 1) extracts the contents of fer_executables.tar.gz into $FER_DIR
##           after renaming any existing files that would have been overwritten
## Option 2) modifies ferret_paths_template and pyferret_template files to 
##           specify locations of ferret software and demo data sets to create 
##           the ferret_paths and pyferret files.
## All changes are recorded, with a timestamp, in the log file
## $FER_DIR/bin/Finstall.log


### Assign $fer_dir, the desired FER_DIR value
get_fer_dir() {
    if [ -n "${FER_DIR}" ]; then
        fer_dir="${FER_DIR}"
        echo " "
        echo " The environment variable FER_DIR is currently defined as "
        echo " '${FER_DIR}' "
        echo " This is the directory where the 'fer_environment.tar.gz' "
        echo " file was installed/extracted. "
        echo " "
        read -p " Is that correct and acceptable (y/n) [y] " ans
        if [ -z "${ans}" ] || [ "${ans}" = "Y" ] || [ "${ans}" = "y" ]; then
            return 0
        fi
    fi

    until [ 0 = 1 ]; do
        echo " "
        echo " Enter the name of the directory where the 'fer_environment.tar.gz' "
        echo " file was installed/extracted (FER_DIR).  The location recommended "
        echo " in the Ferret installation guide was '/usr/local/ferret'. "
        echo " "
        read -p " FER_DIR --> " fer_dir
        if [ ! -d "${fer_dir}" ]; then
            echo " '${fer_dir}' is not a directory"
        else
#           resolve relative pathnames
            fer_dir=`cd "${fer_dir}" ; pwd`
            if [ ! -x "${fer_dir}/bin/Fenv" ]; then
                echo " The Ferret environment files are not in "
                echo " '${fer_dir}' "
            else
                return 0
            fi
        fi
    done
#   should not get here - return error
    return 1
}


### Assign $fer_dsets, the desired FER_DSETS value
get_fer_dsets() {
    if [ -n "${FER_DSETS}" ]; then
        fer_dsets="${FER_DSETS}"
        echo " "
        echo " The environment variable FER_DSETS is currently defined as "
        echo " '${FER_DSETS}' "
        echo " This is the directory where the 'fer_dsets.tar.gz' file was "
        echo " installed/extracted."
        echo " "
        read -p " Is that correct and acceptable (y/n) [y] " ans
        if [ -z "${ans}" ] || [ "${ans}" = "Y" ] || [ "${ans}" = "y" ]; then
            return 0
        fi
    fi

    until [ 0 = 1 ]; do
        echo " "
        echo " Enter the name of the directory where the 'fer_dsets.tar.gz' "
        echo " file was installed/extracted (FER_DSETS)."
        echo " "
        read -p " FER_DSETS --> " fer_dsets
        if [ ! -d "${fer_dsets}" ]; then
            echo " '${fer_dsets}' is not a directory"
        else
#           resolve relative pathnames
            fer_dsets=`cd "${fer_dsets}" ; pwd`
            if [ ! -f "${fer_dsets}/data/coads_climatology.cdf" ]; then
                echo " The Ferret demonstration data files are not in "
                echo " '${fer_dsets}' "
            else
                return 0
            fi
        fi
    done
#   should not get here - return error
    return 1
}


### Assign $ferpaths_dir, the directory to contain the ferret_paths.* files
get_ferpaths_dir() {
    until [ 0 = 1 ]; do
        echo " "
        echo " Enter the name of the directory where you want to place "
        echo " the newly created 'ferret_paths.csh', 'ferret_path.sh', "
        echo " pyferret files; for example, '/usr/local/bin'."
        echo " "
        read -p " desired ferret_paths location --> " ferpaths_dir
        if [ ! -d "${ferpaths_dir}" ]; then
            echo " '${ferpaths_dir}' is not a directory"
        else
#           resolve relative pathnames
            ferpaths_dir=`cd "${ferpaths_dir}" ; pwd`
#           if ferret_paths* exists, check to see if it's OK to replace
            if [ -f "${ferpaths_dir}/ferret_paths.csh" ] || \
               [ -f "${ferpaths_dir}/ferret_paths.sh" ] ||
               [ -f "${ferpaths_dir}/pyferret.csh" ] ||
               [ -f "${ferpaths_dir}/pyferret.sh" ] ; then
                echo " "
                if [ -f "${ferpaths_dir}/ferret_paths.csh" ]; then
                    echo " ${ferpaths_dir}/ferret_paths.csh already exists"
                fi
                if [ -f "${ferpaths_dir}/ferret_paths.sh" ]; then
                    echo " ${ferpaths_dir}/ferret_paths.sh already exists"
                fi
                if [ -f "${ferpaths_dir}/pyferret.csh" ]; then
                    echo " ${ferpaths_dir}/pyferret.csh already exists"
                fi
                if [ -f "${ferpaths_dir}/pyferret.sh" ]; then
                    echo " ${ferpaths_dir}/pyferret.sh already exists"
                fi
                read -p " Rename and create new? (n/y) [n] " ans
                if [ "${ans}" = "Y" ] || [ "${ans}" = "y" ]; then
                    return 0
                fi
                read -p " Select a different directory? (y/n) [y] " ans
                if [ -n "${ans}" ] && [ "${ans}" != "Y" ] && [ "${ans}" != "y" ]; then
                    return 1
                fi
            else
                return 0
            fi
        fi
    done
#   should not get here - return error
    return 1
}


### assign $ferpaths_link, the link destination, if any, for ferret_paths
get_ferpaths_link() {
    echo " "
    echo " To duplicate behavior found in older version of Ferret, you can "
    echo " create a link (shortcut) 'ferret_paths' that refers to either "
    echo " 'ferret_paths.csh' or 'ferret_paths.sh'.  This is simply a "
    echo " convenience for users and should only be done on systems where "
    echo " all Ferret users work under the same shell (such as tcsh or bash). "
    echo " The files 'ferret_path.csh' and 'ferret_paths.sh' can always be "
    echo " used regardless of the answer to this question. "
    until [ 0 = 1 ]; do
        echo " "
        echo " ferret_paths link options: "
        echo "    c - link to ferret_paths.csh (all users work under tcsh, csh) "
        echo "    s - link to ferret_paths.sh (all users work under bash, dash, ksh, sh) "
        echo "    n - do not create the link (use ferret_paths.csh or ferret_paths.sh)"
        read -p " ferret_paths link to create? (c/s/n) [n] --> " ans
        if [ -z "$ans" ] || [ "$ans" = 'n' ] || [ "$ans" = 'N' ]; then
           ferpaths_link=''
           return 0
        elif [ "$ans" = 'c' ] || [ "$ans" = 'C' ]; then
           ferpaths_link='ferret_paths.csh'
           return 0
        elif [ "$ans" = 's' ] || [ "$ans" = 'S' ]; then
           ferpaths_link='ferret_paths.sh'
           return 0
        fi
    done
#   should not get here - return error
    return 1
}


### Get python_executable and python_subdirectory
get_python_vars() {
    echo " "
    echo " Enter the desired python executable to use for running PyFerret. "
    echo " This may simply be 'python', but on systems with multiple versions "
    echo " of python, you need to specify the version to use, such as 'python2.6' "
    echo " or 'python2.7', or the full-path name to desired version of python. "
    until [ 0 = 1 ]; do
        echo " "
        read -p " python executable to use: ['python'] --> " ans
        if [ -z "$ans" ]; then
            ans='python'
        fi
#       expand to the full path name, just to be safe (may not be necessary)
        python_executable=`which "$ans"`
#       assign python_subdirectory as 'python2.6' or 'python2.7' using the version
#       number reported by the python executable (which validates the python executable)
        python_subdirectory=`${ans} -c "import sys; print 'python%i.%i' % sys.version_info[:2]"`
        if echo "${python_subdirectory}" | grep -q '^python2\.[67]$'; then
            return 0
        elif echo "${python_subdirectory}" | grep -q '^python'; then
            echo " ${ans} appears to be ${python_subdirectory}; only python2.6 or python2.7 supported "
        else
            echo " ${ans} does not appear to be a valid python executable "
        fi
    done
#   should not get here - return error
    return 1
}


### Write a message to ${fer_dir}/bin/Finstall.log (creating it if it does not exist)
write_log_message() {
#   Sanity check
    if [ -z "${fer_dir}" ]; then
        echo " "
        echo " Unexpected script error: fer_dir not defined in write_log_message "
        exit 1
    fi
#   get_fer_dir ensures ${fer_dir}/bin already exists
#   Create Finstall.log file if it does not exist
    logfile="${fer_dir}/bin/Finstall.log"
    if [ ! -f "${logfile}" ]; then
        timestamp=`/bin/date +' %D %T'`
        if ! echo "${timestamp} Created Finstall.log " > "${logfile}" ; then
            return 1
        fi
        echo " "
        echo " Created Finstall.log in ${fer_dir}/bin "
    fi

    timestamp=`/bin/date +' %D %T'`
    if ! echo "${timestamp} $1 " >> "${logfile}" ; then
        return 1
    fi
}


### Edit the ferret_paths_template.{csh,sh} files to create the ferret_paths.{csh,sh} files 
### and edit the pyferret_template file to create the pyferret file.
create_ferret_paths_and_pyferret() {
#   Check for existing ferret_paths.csh
    if [ -f "${ferpaths_dir}/ferret_paths.csh" ]; then
        if mv -f "${ferpaths_dir}/ferret_paths.csh" "${ferpaths_dir}/ferret_paths.csh.old"; then
            write_log_message "Renamed existing ${ferpaths_dir}/ferret_paths.csh"
            write_log_message "              to ${ferpaths_dir}/ferret_paths.csh.old"
            echo " "
            echo " Renamed existing ${ferpaths_dir}/ferret_paths.csh "
            echo "               to ${ferpaths_dir}/ferret_paths.csh.old "
        fi
    fi
#   Create new ferret_paths.csh
    if sed -e "/setenv FER_DIR/c\\
setenv FER_DIR \"${fer_dir}\"" \
           -e "/setenv FER_DSETS/c\\
setenv FER_DSETS \"${fer_dsets}\"" \
           -e "/set python_exe = /c\\
set python_exe = \"${python_executable}\"" \
           -e "/set python_subdir = /c\\
set python_subdir = \"${python_subdirectory}\"" \
           "${fer_dir}/bin/ferret_paths_template.csh" \
           > "${ferpaths_dir}/ferret_paths.csh" ; then
        write_log_message "Created ${ferpaths_dir}/ferret_paths.csh"
        echo " "
        echo " Created ${ferpaths_dir}/ferret_paths.csh "
    else
        write_log_message "Unable to create ${ferpaths_dir}/ferret_paths.csh"
        echo " "
        echo " Unable to create ${ferpaths_dir}/ferret_paths.csh "
    fi
#   Check for existing ferret_paths.sh
    if [ -f "${ferpaths_dir}/ferret_paths.sh" ]; then
        if mv -f "${ferpaths_dir}/ferret_paths.sh" "${ferpaths_dir}/ferret_paths.sh.old"; then
            write_log_message "Renamed existing ${ferpaths_dir}/ferret_paths.sh"
            write_log_message "              to ${ferpaths_dir}/ferret_paths.sh.old"
            echo " "
            echo " Renamed existing ${ferpaths_dir}/ferret_paths.sh "
            echo "               to ${ferpaths_dir}/ferret_paths.sh.old "
        fi
    fi
#   Create new ferret_paths.sh
    if sed -e "/export FER_DIR=/c\\
export FER_DIR=\"${fer_dir}\"" \
           -e "/export FER_DSETS=/c\\
export FER_DSETS=\"${fer_dsets}\"" \
           -e "/python_exe=/c\\
python_exe=\"${python_executable}\"" \
           -e "/python_subdir=/c\\
python_subdir=\"${python_subdirectory}\"" \
           "${fer_dir}/bin/ferret_paths_template.sh" \
           > "${ferpaths_dir}/ferret_paths.sh" ; then
        write_log_message "Created ${ferpaths_dir}/ferret_paths.sh"
        echo " "
        echo " Created ${ferpaths_dir}/ferret_paths.sh "
    else
        write_log_message "Unable to create ${ferpaths_dir}/ferret_paths.sh"
        echo " "
        echo " Unable to create ${ferpaths_dir}/ferret_paths.sh"
    fi
#   Check for existing ferret_paths
    if [ -f "${ferpaths_dir}/ferret_paths" ]; then
        if mv -f "${ferpaths_dir}/ferret_paths" "${ferpaths_dir}/ferret_paths.old"; then
            write_log_message "Renamed existing ${ferpaths_dir}/ferret_paths"
            write_log_message "              to ${ferpaths_dir}/ferret_paths.old"
            echo " "
            echo " Renamed existing ${ferpaths_dir}/ferret_paths "
            echo "               to ${ferpaths_dir}/ferret_paths.old "
        fi
    fi
#   Link ferret_paths to the appropriate file
    if [ -n "${ferpaths_link}" ]; then
        if ( cd "${ferpaths_dir}" ; ln -s "${ferpaths_link}" "ferret_paths" ) ; then
            write_log_message "Created ${ferpaths_dir}/ferret_paths"
            write_log_message "    as a link to ${ferpaths_link}"
            echo " "
            echo " Created ${ferpaths_dir}/ferret_paths "
            echo "     as a link to ${ferpaths_link} "
        else
            write_log_message "Unable to create ${ferpaths_dir}/ferret_paths"
            echo " "
            echo " Unable to create ${ferpaths_dir}/ferret_paths "
        fi
    fi
#   Check for existing pyferret.csh and move it out of the way
    if [ -f "${fer_dir}/bin/pyferret.csh" ]; then
        if mv -f "${fer_dir}/bin/pyferret.csh" "${fer_dir}/bin/pyferret.csh.old"; then
            write_log_message "Renamed existing ${fer_dir}/bin/pyferret.csh"
            write_log_message "              to ${fer_dir}/bin/pyferret.csh.old"
            echo " "
            echo " Renamed existing ${fer_dir}/bin/pyferret.csh "
            echo "               to ${fer_dir}/bin/pyferret.csh.old "
        fi
    fi
#   Check for existing pyferret.sh and move it out of the way
    if [ -f "${fer_dir}/bin/pyferret.sh" ]; then
        if mv -f "${fer_dir}/bin/pyferret.sh" "${fer_dir}/bin/pyferret.sh.old"; then
            write_log_message "Renamed existing ${fer_dir}/bin/pyferret.sh"
            write_log_message "              to ${fer_dir}/bin/pyferret.sh.old"
            echo " "
            echo " Renamed existing ${fer_dir}/bin/pyferret.sh "
            echo "               to ${fer_dir}/bin/pyferret.sh.old "
        fi
    fi
#   Check for existing pyferret
    if [ -f "${fer_dir}/bin/pyferret" ]; then
        if mv -f "${fer_dir}/bin/pyferret" "${fer_dir}/bin/pyferret.old"; then
            write_log_message "Renamed existing ${fer_dir}/bin/pyferret"
            write_log_message "              to ${fer_dir}/bin/pyferret.old"
            echo " "
            echo " Renamed existing ${fer_dir}/bin/pyferret "
            echo "               to ${fer_dir}/bin/pyferret.old "
        fi
    fi
#   Create new pyferret
    if sed -e "/python_exe=/c\\
python_exe=\"${python_executable}\"" \
           -e "/python_subdir=/c\\
python_subdir=\"${python_subdirectory}\"" \
           "${fer_dir}/bin/pyferret_template" \
           > "${fer_dir}/bin/pyferret" ; then
        chmod +x "${fer_dir}/bin/pyferret"
        write_log_message "Created executable script ${fer_dir}/bin/pyferret"
        echo " "
        echo " Created executable script ${fer_dir}/bin/pyferret"
    else
        write_log_message "Unable to create ${fer_dir}/bin/pyferret"
        echo " "
        echo " Unable to create ${fer_dir}/bin/pyferret"
    fi
}


### Assign $ferexec_dir, the directory containing the fer_executables.tar.gz file
get_ferexec_dir() {
    until [ 0 = 1 ]; do
        echo " "
        echo " Enter the name of the directory containing the "
        echo " 'fer_executables.tar.gz file. "
        read -p " 'fer_executables.tar.gz' location --> " ferexec_dir
        if [ ! -d "${ferexec_dir}" ]; then
            echo " '${ferexec_dir}' is not a directory"
        else
#           resolve relative pathnames
            ferexec_dir=`cd "${ferexec_dir}" ; pwd`
            if [ ! -f "${ferexec_dir}/fer_executables.tar.gz" ]; then
                echo " 'fer_executables.tar.gz' is not in ${ferexec_dir}"
            else
                return 0
            fi
        fi
    done
#   should not get here - return error
    return 1
}


### Install the contents of $ferexec_dir/fer_executables.tar.gz into $fer_dir
install_execs() {
    write_log_message "Installing/updating from ${ferexec_dir}/fer_executables.tar.gz"

#   Get the list of files in the tar file
    exetar_files=`tar tzf ${ferexec_dir}/fer_executables.tar.gz`
    if [ -z "${exetar_files}" ]; then
#        tar should have already printed a more appropriate error message
         write_log_message "No files found in ${ferexec_dir}/fer_executables.tar.gz"
         echo " "
         echo " No files found in ${ferexec_dir}/fer_executables.tar.gz "
         return 1
    fi

#   Make sure the tar file is the right format
    lib_files=`tar tzf ${ferexec_dir}/fer_executables.tar.gz lib`
    if [ -z "${lib_files}" ]; then
         write_log_message "Aborting - old style fer_executables.tar.gz"
         echo " "
         echo " Aborting - old style fer_executables.tar.gz "
         return 1
    fi

#   Rename old files if they exist
    echo " Renaming (by appending '.old') any existing files in ${fer_dir} "
    echo "     that will be replaced by files in ${ferexec_dir}/fer_executables.tar.gz "
    for exefile in ${exetar_files} ; do
        if [ -f "${fer_dir}/${exefile}" ]; then
            if mv -f "${fer_dir}/${exefile}" "${fer_dir}/${exefile}.old" ; then
                write_log_message "Renamed existing ${exefile} to ${exefile}.old"
            else
                write_log_message "Aborting - unable to rename ${exefile}"
                echo " "
                echo " Aborting - unable to rename ${fer_dir}/${exefile} "
                return 1
            fi
        fi
    done

#   Extract the files into $fer_dir
    echo " Extracting files from ${ferexec_dir}/fer_executables.tar.gz "
    echo "                    to ${fer_dir} "
    if ( cd "${fer_dir}" ; tar xzf "${ferexec_dir}/fer_executables.tar.gz" ) ; then
        for exefile in ${exetar_files} ; do
            write_log_message "Extracted ${exefile}"
        done
    else
        return 1
    fi
}


### Main script
### Info message printed only once
echo " "
echo " This script can do two things for you to help install Ferret: "
echo " "
echo " (1) Install the Ferret executables into FER_DIR/bin from the "
echo "     fer_executables.tar.gz file."
echo " "
echo "     You will want to run this option if you are installing "
echo "     Ferret for the first time or if you are updating Ferret "
echo "     with new executables."
echo " "
echo " (2) Modify the shell scripts 'ferret_paths_template.csh' and "
echo "     'ferret_paths_template.sh' to set environment variables "
echo "     FER_DIR and FER_DSETS to the directories at your site "
echo "     containing the Ferret software and demonstration data. "
echo " "
echo "     The files 'ferret_paths.csh' and 'ferret_paths.sh' are "
echo "     created in a directory you choose.  Furthermore, the link "
echo "     (shortcut) 'ferret_paths' can be created which refers to "
echo "     either 'ferret_paths.csh' or 'ferret_paths.sh'. "
echo " "
echo "     Sourcing one of these files ('source ferret_paths.csh' "
echo "     for csh or tcsh, '. ferret_paths.sh' for bash, sh ksh, "
echo "     or dash) will set up a user's environment for running "
echo "     ferret. "
echo " "
echo "     This also creates the executable shell scripts "
echo "     'pyferret.csh' and 'pyferret.sh'. "
echo " "
echo "     You will want to run this option if you are installing "
echo "     Ferret for the first time or if you relocated where "
echo "     Ferret is installed. "
echo " "

### Print menu and act on choice
until [ 0 = 1 ]; do
    echo " "
    echo " Enter your choice:"
    echo " (1) Install executables, (2) Customize ferret_paths files, (3,q,x) Exit"
    read -p " (1, 2, 3, q, x) --> " choice
    case "$choice" in
        1)
            echo " "
            echo " Install executables..."
            if get_fer_dir && get_ferexec_dir; then
                if ! install_execs; then
                    echo " "
                    echo " There is a problem manipulating files in "
                    echo " "$fer_dir" "
                    echo " Check your privileges to change files in that directory "
                    echo " and try again. "
                fi
            fi
            ;;
        2)
            echo " "
            echo " Customize ferret_paths files..."
            if get_fer_dir && get_fer_dsets && get_ferpaths_dir && \
               get_ferpaths_link && get_python_vars; then
                create_ferret_paths_and_pyferret
            else
                echo " "
                echo " ferret_paths files NOT created "
            fi
            ;;
        3 | 'q' | 'Q' | 'x' | 'X')
            exit 0
            ;;
        *)
            ;;
    esac
done
# should not get here - return error
exit 1

