#!/bin/ksh

########################################################################
# fiper4all - deploy and start a SEE Server for testing purposes.
#
# See comments in file fiper4all.param for required settings.
# See calls to 'checkVar' and 'defaultVar' below for documentation on
# properties required by this file.
#
# There are a few environment variables that will affect the behavior of
# this script:
#    SH_DEBUG - if set, produce debugging output from the shell (set -e).
#    F4ALL_VERBOSE - if set, produce verbose progress messages.
#    F4ALL_KEEP - if set, keep all temporary files.
########################################################################

usage() {
    cat <<!
Usage: $(basename "$script") PropFile UpdateOptions

  PropFile - property file that contains SEE server configuration.
          Copy file fiper4all.param in this directory to a local directory and edit
          to create the properties list.  The file should be self-documenting.

  UpdateOptions - one or more of the following options, separated by commas.
          These tell the script what processing to do.  Each step performs
          earlier steps if they have not been done yet, and will then 
          perform subsequent steps. 
    prepconfig - prepare config directory with editable configuration files
    create  - create DB and EJB profile.  Drop and re-create if already exist.
          implies 'config'
    config  - Configure WAS/WL and DB tables.  Reset and re-create if already done.
          implies 'deploy'
    deploy  - deploy EAR/WAR files
          implies 'publish'
    publish - publish Components to the ACS library.

  The following update options stand alone.  They can be combined with the above.
    all      - alias for 'deploy' that is easier to remember.
    build    - build the EAR/WAR files.  Requires a workspace with the
               SMAFIPSEE, SMAFIPwebtop, and SMAFIPwebdashboard Frameworks.
    cleardb  - erase the contents of the SEE Database and File Manager.
    nodb     - skip all database operations.  Use if there is no local DB install.
          Still does websphere/weblogic operations.
    stop     - stop Websphere/WebLogic server (if it is currently running).
    start    - start Websphere/WebLogic server (if it is currently not running).
    restart  - restart Websphere/WebLogic server.

    To set up a new SEE server from a Development workspace, use 'build,all'.
!
}

# Load useful shell functions.  Location is always relative to this file.
script="$0"
shell_dir=$(dirname "$script")
. "$shell_dir/fiper-functions.sh"

# Provide help if requested
if expr "$1" : '-[hH?].*' >$NUL; then
    usage
    exit 0
fi

# Get options:  property file and operation list
propfile=$(makeAbsolute $1)
operationList=$2

if [ ! "$propfile" -o ! "$operationList" ]; then
    usage
    exit 1
fi

# Default (and normalize) FIPER_HOME
# Use 2 levels up from location of this script if FIPER_HOME not set
# to a real directory.
# Set this here as the Properties file may override below,
# but if it doesn't override, it may still need the value.
if [ "$FIPER_HOME" -a ! -d "$FIPER_HOME" ]; then
    # Prevent use of an invalid FIPER_HOME.  Would cause cannonPath to error.
    FIPER_HOME=''
fi
export FIPER_HOME=$(cannonPath ${FIPER_HOME:-$shell_dir/../../..})

# Read the properties file
if [ ! -f "$propfile" ]; then
    fail "Properties file '$propfile' does not exist."
fi
msg "Reading property file '$propfile'"
. "$propfile" || fail "Error reading properties file $propfile"

# Parse operation list, setting various op_* variables
IFS=','
for op in $operationList; do
    case $op in
        create)  op_create=1 ;;
        config)  op_config=1 ;;
        deploy)  op_deploy=1 ;;
        publish) op_publish=1 ;;
        build)   op_build=1 ;;
        cleardb) op_cleardb=1 ;;
        nodb)    op_nodb=1 ;;
        stop)    op_stop=1 ;;
        start)   op_start=1 ;;
        restart) op_restart=1 ;;
        prepconfig) op_prepconfig=1 ;;
        all)     
            # all currently defaults to 'deploy'.  This could change
            op_deploy=1 
            ;;
        *)  err "Unknown processing option: $op"
            usage
            exit 1    
            ;;
    esac
done

unset IFS

# Process transitive options
if [ "$op_create" ]; then
    op_config=1
    op_prepconfig=1
fi
if [ "$op_config" ]; then
    op_deploy=1
    op_prepconfig=1
fi
if [ "$op_deploy" ]; then
    op_publish=1
    op_prepconfig=1
fi

msg "fiper4all options:  create=$op_create  config=$op_config  deploy=$op_deploy  publish=$op_publish  build=$op_build  cleardb=$op_cleardb  nodb=$op_nodb prepconfig=$op_prepconfig"

# Normalize some values without resetting them
FIPER_HOME=$(stdPath "$FIPER_HOME")
FIPER_CONF=$(stdPath "$FIPER_CONF")
CATInstallPath=$(stdPath "$CATInstallPath")
tmp4all=$(stdPath "$tmp4all")
LOG_DIR=$(stdPath "$LOG_DIR")
SERVER_TYPE=$(upcase "$SERVER_TYPE")
DB_TYPE=$(upcase "$DB_TYPE")
FIPER_FILEMGR=$(stdPath "$FIPER_FILEMGR")
FIPER_TEMP=$(stdPath "$FIPER_TEMP")

########################################################################
### Check shell variables used by this script and set in the param file.
########################################################################

checkVar FIPER_HOME reffiles/SMAFIPserver/deploy/fiper4all.sh 
                                                 # Install or workspace dir.
defaultVar FIPER_CONF "${FIPER_HOME}/../config"  # Location of acs.properties
defaultVar CATInstallPath "${FIPER_HOME}"        # Search path for RTV
defaultVar tmp4all "${TMPDIR:-${TEMP}}"          # Directory for temporary files.
defaultVar LOG_DIR "${tmp4all}/fiper4all"        # directory for log files
checkVar SERVER_TYPE         # EJB server type "jboss" "websphere" or "weblogic" only
checkVar SERVER_NAME         # Name of server (host name and CPR file name)
checkVar DB_TYPE             # Database type, "MySQL" "oracle" or "db2"
checkVar SEE_USER            # User with admin access to the ACS
checkVar SEE_USER_PW         # Password for SEE_USER
checkVar FIPER_FILEMGR       # Directory to hold file manager files.  MUST be set.  Will be created if needed.
checkVar FIPER_TEMP          # Cache directory for ACS.  Will be created if needed

# Try to default ADL_IMAGE_DIR if not set.
if [ ! "$ADL_IMAGE_DIR" ]; then
    if [ -d "$FIPER_HOME/../SMAFIPSEE" ]; then
        ADL_IMAGE_DIR=$(cannonPath "$FIPER_HOME/..")
    fi
    # Do not check here.  If ADL_IMAGE_DIR isn't set and can't default, leave unset.
fi

checkErr

# Now do validation too complex for checkVar and defaultVar
if [ "$SERVER_TYPE" != 'WEBSPHERE' -a "$SERVER_TYPE" != 'WEBLOGIC' -a "$SERVER_TYPE" != 'JBOSS' ]; then
    err "SERVER_TYPE must be JBOSS, WEBSPHERE or WEBLOGIC.  Currently SERVER_TYPE=${SERVER_TYPE}"
fi

if [ "$DB_TYPE" != 'ORACLE' -a "$DB_TYPE" != 'DB2' -a "$DB_TYPE" != 'MYSQL' -a "$DB_TYPE" != 'DERBY' ]; then
    err "DB_TYPE must be MYSQL, ORACLE or DB2.  Currently DB_TYPE=${DB_TYPE}"
fi

if [ "$SERVER_TYPE" = 'WEBLOGIC' -a "$DB_TYPE" = 'DB2' ]; then
    err "Combination of SERVER_TYPE=WEBLOGIC and DB_TYPE=DB2 is not supported"
fi

if [ "$SERVER_TYPE" = 'WEBLOGIC' -a "$DB_TYPE" = 'MYSQL' ]; then
    err "Combination of SERVER_TYPE=WEBLOGIC and DB_TYPE=MYSQL is not supported"
fi

if [ "$SERVER_TYPE" = 'WEBSPHERE' -a "$DB_TYPE" = 'MYSQL' ]; then
    err "Combination of SERVER_TYPE=WEBLOGIC and DB_TYPE=MYSQL is not supported"
fi

if [ "$SERVER_TYPE" = 'JBOSS' -a ! \( "$DB_TYPE" = 'MYSQL' -o "$DB_TYPE" = "DERBY" \) ]; then
    err "Combination of SERVER_TYPE=JBOSS and DB_TYPE other than MYSQL or DERBY is not supported"
fi

if [ "$op_build" -a ! -d "$ADL_IMAGE_DIR/SMAFIPSEE" ]; then
    err "Build of EAR file requested but not in a development worksspace with framework SMAFIPSEE."
fi

if [ ! "$op_build" -a "$op_deploy" ]; then
    # Deploying and not building.  
    # Force a build if we have no EAR file but do have a development view.
    # Else error, as there is no way to proceed.
    if [ "$SERVER_TYPE" = 'WEBSPHERE' ]; then
        ear="$FIPER_HOME/reffiles/SMAFIPserver/websphere/fiper.ear"
    elif [ "$SERVER_TYPE" = 'WEBLOGIC' ]; then
        ear="$FIPER_HOME/reffiles/SMAFIPserver/weblogic/fiper.ear"
    elif [ "$SERVER_TYPE" = 'JBOSS' ]; then
        ear="$FIPER_HOME/reffiles/SMAFIPserver/jboss/fiper.ear"
    else
        ear=''
    fi
    if [ "$ear" -a ! -f "$ear" ]; then
        # Must build or abort.
        if [ -d "$ADL_IMAGE_DIR/SMAFIPSEE" ]; then
            note "EAR file does not exist.  Running 'build' step."
            op_build=1
        else
            err "EAR file $ear does not exist and not in a development workspace.  Unable to continue."
        fi
    fi
fi

checkErr

# Add FIPER_HOME/code/command to path - presumably this is where publishall and the like are.
addpath "$FIPER_HOME/code/command"

# Export some variables that may be needed.
export CATInstallPath
export FIPER_HOME
export tmp4all
export LOG_DIR

#############################################################################
### Start actual processing
#############################################################################

if [ "$op_build" ]; then
    # Build requires that you be in a workspace
    checkVar ADL_IMAGE_DIR SMAFIPSEE

    # Build also requires a valid os name
    if [ "$MkmkOS_Buildtime" = '' ]; then
        # Default to last part of fiper hope
        MkmkOS_Buildtime=$(basename "$FIPER_HOME")
        msg "Defaulting MkmkOS_Buildtime = '$MkmkOS_Buildtime'."
    fi
    if [ "$MkmkOS_Buildtime" != 'intel_a' -a "$MkmkOS_Buildtime" != 'win_b64' -a \
         "$MkmkOS_Buildtime" != 'linux_a64' -a "$MkmkOS_Buildtime" != 'linux_b64' ]; then
        err "Build requires valid build OS, but MkmkOS_Buildtime = '$MkmkOS_Buildtime'."
    fi
fi

if [ "$op_nodb" -a "$op_cleardb" ]; then
    err "Options 'nodb' and 'cleardb' cannot be combined."
fi

# Check if there is anything to do.  Transitive options set op_publish for ANY server op.
#if [ ! "$op_publish" -a ! "$op_build" -a ! "$op_cleardb" ]; then
#    err "No action specified.  Must specify 'build', 'cleardb' or one of the option"
#    err "    'create', 'config', 'deploy', or 'all'"
#fi

checkErr

########################################################################
### Create new log directory.  Leave old ones around.
########################################################################

# Create temp directory if needed
# Then normalize it.  Cannot do this until I know it exists.
if [ ! -d "$tmp4all" ]; then
    mkdir -p "$tmp4all" || fail "Unable to create tmp4all directory $tmp4all"
fi
tmp4all=$(cannonPath "$tmp4all")
msg "tmp4all = $tmp4all"
# Force EVERYONE to use this temp directory
export TMPDIR="$tmp4all"
export TEMP=$(localPath "$tmp4all")
export TMP=$(localPath "$tmp4all")

# NOTE: cannot use 'cmd' here, as it relies on LOG_DIR.
# Make LOG_DIR unique if needed.
if [ -e "$LOG_DIR" ]; then
    LOG_DIR="${LOG_DIR}-$(date "+%y%m%d-%H%M")"
fi
mkdir -p "$LOG_DIR"
if [ ! -d "$LOG_DIR" ]; then
    fail "Unable to create log directory $LOG_DIR"
fi
LOG_DIR=$(cannonPath "$LOG_DIR")
note "Logging to directory $LOG_DIR"

# Create other directories that may be needed.
if [ ! -d "$FIPER_FILEMGR" ]; then
    mkdir -p "$FIPER_FILEMGR" || fail "Unable to create FIPER_FILEMGR directory $FIPER_FILEMGR"
fi
if [ ! -d "$FIPER_TEMP" ]; then
    mkdir -p "$FIPER_TEMP" || fail "Unable to create ACS Temp directory FIPER_TEMP = $FIPER_TEMP"
fi

########################################################################
# Create FIPER_CONF and populate if it doesn't exist.
########################################################################

if [ ! -d "$FIPER_CONF" ]; then
    cmd "mkdir '$FIPER_CONF'" || fail "Cannot create Configuration directory FIPER_CONF='$FIPER_CONF'."
fi
FIPER_CONF=$(cannonPath "$FIPER_CONF")

# cpif - copy a file if the destination file does not already exist.
#    Error if the copy fails (destination directory unwritable, or source file doesn't exist)
cpif() {
    s=$1
    d=$2
    if [ ! -f "$d" ]; then
        msg "cp '$s' '$d'"
        cp "$s" "$d"
        if [ $? -ne 0 ]; then
            fail "Error copying '$s' to '$d'.  Cannot continue."
        fi
    fi
}

##########################################################################
# Build EAR/WAR if requested
##########################################################################

if [ "$op_build" ]; then
    logfile="$LOG_DIR/fiper-build.log"
    args=''
    [ "$SERVER_TYPE" = "WEBSPHERE" ] && args="$args -was" 
    [ "$SERVER_TYPE" = "WEBLOGIC" ] && args="$args -wl" 
    [ "$SERVER_TYPE" = "JBOSS" ] && args="$args -jboss" 
        args="$args -ear"
        [ "$WEBTOP_INSTALL" ] && args="$args -web" 
        [ "$WEBDASH_INSTALL" ] && args="$args -dash" 
    note "Building EAR/WAR files"
    export JBOSS_HOME WAS_HOME WL_HOME MkmkOS_Buildtime CATInstallPath ADL_IMAGE_DIR
    cmd "'$ADL_IMAGE_DIR/SMAFIPSEE/Data.d/command/fiper-build.sh' $args" "$logfile"
    if [ $? -ne 0 ]; then
        fail "Build of EAR/WAR files failed.  See log in $logfile"
    fi
fi

##########################################################################
# Set up Database
##########################################################################

# Do common setup for both DB2 and Oracle
if [ "$op_create" ]; then
    dbArg='create'
elif [ "$op_config" ]; then
    dbArg='config'
elif [ "$op_cleardb" ]; then
    dbArg='clear'
elif [ "$op_publish" ]; then
    dbArg='check'
else
    # This happens if only 'build' is specified.  
    # Suppress all database operations.
    dbArg=''
fi

if [ "$DB_TYPE" = 'DB2' ]; then
    dbCmd="$shell_dir/fiper4db2.sh"
elif [ "$DB_TYPE" = 'ORACLE' ]; then
    dbCmd="$shell_dir/fiper4oracle.sh"
else # DB_TYPE = MYSQL
    dbCmd="$shell_dir/fiper4mysql.sh" 
fi

# Pass of DB processing to separate script
if [ "$op_nodb" -o ! "$dbArg" ]; then
    note "Skipping DB operations."
else
    # Must stop server before can reset the database.
    if [ "$op_create" -o "$op_config" -o "$op_cleardb" ]; then
        if [ "$SERVER_TYPE" = 'WEBSPHERE' ]; then
            serverCmd="$shell_dir/fiper4websphere.sh" 
        elif [ "$SERVER_TYPE" = 'WEBLOGIC' ]; then
            serverCmd="$shell_dir/fiper4weblogic.sh" 
        else # SERVER_TYPE = 'JBOSS'
            serverCmd="$shell_dir/fiper4jboss.sh" 
        fi
        cmd "'$serverCmd' '$propfile' stop" "$LOG_DIR/stopServer.log"
        if [ $? -ne 0 ]; then
            fail "Unable to stop server. See $LOG_DIR/stopServer.log"
        fi
    fi

    note "Creating/Updating $DB_TYPE configration"
    # Do not use 'cmd()' here as it redirects to file and I don't want that.
    msg "Cmd: '$dbCmd' '$propfile' $dbArg"
    "$dbCmd" "$propfile" $dbArg
    if [ $? -ne 0 ]; then
        fail "$DB_TYPE operations failed."
    fi
fi

##########################################################################
# Configure EJB Server and Deploy EAR/WAR
##########################################################################

# Common setup for both server scripts
if [ "$op_create" ]; then
    serverArg='create'
elif [ "$op_config" ]; then
    serverArg='config'
elif [ "$op_deploy" ]; then
    serverArg='deploy'
elif [ "$op_stop" ]; then
    serverArg='stop'
elif [ "$op_start" ]; then
    serverArg='start'
elif [ "$op_restart" ]; then
    serverArg='restart'
else
    # Rare case where no server operation is required.
    # Happens if only argument is 'build' or 'cleardb'
    serverArg=''
fi

if [ "$SERVER_TYPE" = 'WEBSPHERE' ]; then
    serverCmd="$shell_dir/fiper4websphere.sh" 
elif [ "$SERVER_TYPE" = 'WEBLOGIC' ]; then
    serverCmd="$shell_dir/fiper4weblogic.sh" 
else # SERVER_TYPE = 'JBOSS'
    serverCmd="$shell_dir/fiper4jboss.sh" 
fi

# Perform server operation
if [ "$serverArg" ]; then
    note "Creating/Updating $SERVER_TYPE configration"
    # Do not use 'cmd()' here as it redirects to file and I don't want that.
    msg "Cmd: '$serverCmd' '$propfile' $serverArg"
    "$serverCmd" "$propfile" $serverArg
    if [ $? -ne 0 ]; then
        fail "$SERVER_TYPE operations failed."
    fi
else
    msg "Skipping Server configuration."
fi

##########################################################################
# publish components to ACS Library.
##########################################################################

if [ "$op_publish" ]; then
    note "Publishing components to server $SERVER_NAME"
    pubcmd=$(findFile publishall${SCRIPT} "$PATH")
    export FIPER_CONF CATInstallPath 
    logfile="$LOG_DIR/publish.log"
    cmd "'$pubcmd' profile:$SERVER_NAME 'user:$SEE_USER' 'pw:$SEE_USER_PW' logonprompt:no" "$logfile"
    if [ $? -ne 0 ]; then
        # There were errors from publishall.  See if they are warnings or fatal.
        # Consier the publish successful if word component published.
        if grep 'Published metamodel com.engineous.component.Word from SMAFMMword.jar' $logfile >$NUL; then
            warn "Publish operations had errors. See log in $logfile"
        else
            fail "Publishall failed.  See log in $logfile"
        fi
    fi
fi


##########################################################################
# prepare workspace with editable configuration files
##########################################################################

if [ "$op_prepconfig" ]; then
    note "Preparing configuration files in $FIPER_CONF"
    confSrc="$FIPER_HOME/reffiles/SMAFIPconfig"
    cpif "$confSrc/standalone.cpr" "$FIPER_CONF/standalone.cpr"
    cpif "$confSrc/license.dat" "$FIPER_CONF/license.dat"
    cpif "$confSrc/grid_ssh_config.txt" "$FIPER_CONF/grid_ssh_config.txt" 
    cpif "$confSrc/station.properties" "$FIPER_CONF/station.properties" 
    cpif "$confSrc/isight.properties" "$FIPER_CONF/isight.properties" 
fi
