#! /bin/sh
## NOAA PMEL TMAP
## Finstall
## Does two things:
## 1) modifies 'ferret_paths template' to specify locations of ferret
##    software and demo data sets and places the result in the indicated
##    sourcing directory as 'ferret_paths'
## 2) extracts the contents of fer_executables.tar.gz into $FER_DIR
##    after renaming any existing files that would have been overwritten
## 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' and 'ferret_path.sh' "
        echo " files; for example, '/usr/local'."
        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" ] ; 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
                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
}


### 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 " 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
        echo " Creating Finstall.log in ${fer_dir}/bin "
        timestamp=`/bin/date +' %D %T'`
        if ! echo "${timestamp} Created Finstall.log " > "${logfile}" ; then
            return 1
        fi
    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
create_ferret_paths() {
#   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
            echo " "
            echo " Renamed existing ${ferpaths_dir}/ferret_paths.csh "
            echo "               to ${ferpaths_dir}/ferret_paths.csh.old "
            write_log_message "Renamed existing ${ferpaths_dir}/ferret_paths.csh"
            write_log_message "              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}\"" \
           "${fer_dir}/bin/ferret_paths_template.csh" \
           > "${ferpaths_dir}/ferret_paths.csh" ; then
        echo " "
        echo " Created ${ferpaths_dir}/ferret_paths.csh "
        write_log_message "Created ${ferpaths_dir}/ferret_paths.csh"
    else
        echo " "
        echo " Unable to create ${ferpaths_dir}/ferret_paths.csh "
        write_log_message "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
            echo " "
            echo " Renamed existing ${ferpaths_dir}/ferret_paths.sh "
            echo "               to ${ferpaths_dir}/ferret_paths.sh.old "
            write_log_message "Renamed existing ${ferpaths_dir}/ferret_paths.sh"
            write_log_message "              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}\"" \
           "${fer_dir}/bin/ferret_paths_template.sh" \
           > "${ferpaths_dir}/ferret_paths.sh" ; then
        echo " "
        echo " Created ${ferpaths_dir}/ferret_paths.sh "
        write_log_message "Created ${ferpaths_dir}/ferret_paths.sh"
    else
        echo " "
        echo " Unable to create ${ferpaths_dir}/ferret_paths.sh"
        write_log_message "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
            echo " "
            echo " Renamed existing ${ferpaths_dir}/ferret_paths "
            echo "               to ${ferpaths_dir}/ferret_paths.old "
            write_log_message "Renamed existing ${ferpaths_dir}/ferret_paths"
            write_log_message "              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
            echo " "
            echo " Created ${ferpaths_dir}/ferret_paths "
            echo "     as a link to ${ferpaths_link} "
            write_log_message "Created ${ferpaths_dir}/ferret_paths"
            write_log_message "    as a link to ${ferpaths_link}"
        else
            echo " "
            echo " Unable to create ${ferpaths_dir}/ferret_paths "
            write_log_message "Unable to create ${ferpaths_dir}/ferret_paths"
        fi
    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
         echo " No files found in ${ferexec_dir}/fer_executables.tar.gz "
         write_log_message "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
         echo " Aborting - old style fer_executables.tar.gz "
         write_log_message "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
                echo " Aborting - unable to rename ${fer_dir}/${exefile} "
                write_log_message "Aborting - unable to rename ${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 "     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; then
                create_ferret_paths
            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

