#!/bin/sh
#

SCRIPT_HOME="$(dirname "$(readlink -f "$0")")"

isSilent=false
updateType=""
hotfixNum=""
hotfixBzNum=""
changesetFile=""
rmChangesetFile=false
serverArchive=""
rmServerArchive=false
pluginPackArchive=""
rmPluginPackArchive=false
prevPluginPackArchive=""
rmPrevPluginPackArchive=false
templateFile=""

# Not sure if we still need this.
pkgVersion="3.2"

function printUsageHelp() {
    echo "$(basename "$0")"' [options] <update_number> <update_id>

This utility will generate an update archive using the previous update
archive as a base and adding the new/updated contents from a new build
based on a change set file.

The new update archive is created in the current work directory.

Parameters:
 update_number
     The update or hotfix number for this plug-in pack update. This
     value should be in the desired format including any left padding.

     For example, if 02 is provided, the value could yield update-02.
     If 2-ER01 is provided, the value could yield update-2-ER01.

 update_id
     The update or hotfix identifier for this plug-in pack update. This
     value should be in the desired format including any left padding.

     update_id is normally a bug tracker number such as 1212499.

Options:
 -h, --help
     This usage help.

 -c, --changeset-file=FILE
     File containing the list of plug-in pack update additions and
     subtractions. See CHANGESET for file format information.

     If not specified, all files from the plug-in pack archive file
     will be included in the new plug-in pack update.

 -o, --prev-plug-in-pack-archive=FILE
     Path and file name of the previously released plug-in pack or
     plug-in pack update archive.

     The contents of this file will server as the base for the final
     plug-in pack update archive.

 -p, --plug-in-pack-archive=FILE
     Path and file name of the plug-in pack archive for this build.

     Some or all of its contents will get included in the final plug-in
     pack update archive based on the contents of the change set file.

     If not specified an attempt is made to locate a plug-in pack
     archive in the current work directory.

 -s, --server-archive=FILE
     Path and file name of the server archive for this build.

     The server archive is required for build and version information
     that will be included in the final plug-in pack update archive.

     The server archive may also be referenced in the change set file
     to include files and updates in the plug-in pack update that are
     delivered as part of the server build. For example, this could
     include samples or additional server side modules that are being
     updated or introduced by the plug-in pack.

     If FILE begins with http:// or https:// an attempt is made to
     retrieve the file from the specified URL.

     If not specified an attempt is made to locate the server archive
     in the current work directory.

 -t, --update-type=TYPE
     Update or component type.

     TYPE can be one of:

       amq   Plug-in pack update for A-MQ
       bpms  Plug-in pack update for BPMS
       brms  Plug-in pack update for BRMS
       eap   Plug-in pack update for EAP
       ews   Plug-in pack update for EWS
       fsw   Plug-in pack update for FSW
       fuse  Plug-in pack update for Fuse
       jdg   Plug-in pack update for JDG
       jdv   Plug-in pack update for JDV
       jpp   Plug-in pack update for Portal
       jws   Alias for ews
       soa   Plug-in pack update for SOA

     If not specified an attempt is made to determine the type based on
     the update file name. For example, if the file name contains the
     pattern "jon-plugin-pack-ews-", the type would be ews.

 --silent
     Suppress standard output and progress information.

     Error messages will still be written to stderr.

CHANGESET

The change set file is a simple text file that lists one new or updated
file per line.

A file prefixed with a minus sign indicates the file must be removed.

The file path is relative to the plug-in pack'"'"'s /plugins or
/jon-plugin-pack-* directory. For example, if the new plug-in pack
build looks like the following:

    /jon-plugin-pack-test-3.3.0.GA/my-plugin-a.jar
    /jon-plugin-pack-test-3.3.0.GA/my-plugin-b.jar

And both my-plugin-a.jar and my-plugin-b.jar should be included in the
new update, the change set file would contain the following:

    my-plugin-a.jar
    my-plugin-b.jar

If the plug-ins included version identifiers in their file names:

    /jon-plugin-pack-test-3.3.0.GA/my-plugin-a-v1.2-b54.jar
    /jon-plugin-pack-test-3.3.0.GA/my-plugin-b-v1.2-b47.jar

And the previous update looked like:

    /plugins/my-plugin-a-v1.1-b17.jar
    /plugins/my-plugin-b-v1.1-b17.jar

The change set file could remove the old versions and add the new using
the following:

    -my-plugin-a-v1.1-b17.jar
    -my-plugin-b-v1.1-b17.jar
    my-plugin-a-v1.2-b54.jar
    my-plugin-b-v1.2-b47.jar

In this case the old files are first removed and then the new files are
added.

Please note that the behavior is to include all files from the previous
update archive and then add explicitly listed files from the new update
archive. This means that all files from the previous archive will be
present in the final update archive unless they are explicitly removed
by an entry in the change set file, or if a new file from the new
build archive is specified in the change set file and has the identical
name of a file from the previous update archive.

You can also specify that a file be added from another archive, either
from the local file system or a web URL. The syntax for the change set
entry is:

    <path or URL to ZIP>!/<path within archive>

For example, if you want to add a new plug-in from a different plug-in
pack, the change set entry might look like:

    http://download.eng.rdu2.redhat.com/released/JBossON/3.3/jon-plugin-pack-eap-3.3.0.GA-update-04.zip!/plugins/rhq-wfly-10-plugin-4.12.0.JON330GA.jar

In this example, the plug-in jon-plugin-pack-eap-3.3.0.GA-update-04.zip
would be downloaded from the URL and the file
plugins/rhq-wfly-10-plugin-4.12.0.JON330GA.jar would be extracted to
the new plug-in pack'"'"'s plugins directory.

When using a _file within an archive_ entry, if the specified
_file path_ is not in the archive, the _file path_ is prefixed with
`plugins/` and another attempt is made to extract the file. If that
fails, a final attempt is made with _file path_ prefixed with the
name of the archive.'
}

##
# Parse command-line arguments and assign the parsed values to their
# respective variables.
#
# $* - A list of arguments to parse.
#
function parseArguments() {
    while [ $# -gt 0 ]; do
        case "$1" in
            '-h'|'--help')
                printUsageHelp
                exit 0
                ;;
            '-c'|'--changeset-file'|'--changeset-file='*)
                if [ ! "$1" = "${1#--changeset-file=}" ]; then
                    changesetFile="${1#--changeset-file=}"
                else
                    changesetFile="$2"
                    shift
                fi
                ;;
            '-s'|'--server-archive'|'--server-archive='*)
                if [ ! "$1" = "${1#--server-archive=}" ]; then
                    serverArchive="${1#--server-archive=}"
                else
                    serverArchive="$2"
                    shift
                fi
                ;;
            '-p'|'--plug-in-pack-archive'|'--plug-in-pack-archive='*)
                if [ ! "$1" = "${1#--plug-in-pack-archive=}" ]; then
                    pluginPackArchive="${1#--plug-in-pack-archive=}"
                else
                    pluginPackArchive="$2"
                    shift
                fi
                ;;
            '-o'|'--prev-plug-in-pack-archive'|'--prev-plug-in-pack-archive='*)
                if [ ! "$1" = "${1#--prev-plug-in-pack-archive=}" ]; then
                    prevPluginPackArchive="${1#--prev-plug-in-pack-archive=}"
                else
                    prevPluginPackArchive="$2"
                    shift
                fi
                ;;
            '-t'|'--update-type'|'--update-type='*)
                if [ ! "$1" = "${1#--update-type=}" ]; then
                    updateType="${1#--update-type=}"
                else
                    updateType="$2"
                    shift
                fi
                ;;
            '-l'|'--template'|'--template='*)
                if [ ! "$1" = "${1#--template=}" ]; then
                    templateFile="${1#--template=}"
                else
                    templateFile="$2"
                    shift
                fi
                # if template is passed in load it now
                if [ -n "$templateFile" ]; then
                 pwd;
                 echo "Sourcing...[${templateFile}]";
                 source "src/main/scripts/${templateFile}";
                 echo "productVersion:[$productVersion]"
                fi
                ;;
            '--silent')
                isSilent=true
                ;;
            *)
                if [ -z "${hotfixNum}" ]; then
                    hotfixNum="$1"
                elif [ -z "${hotfixBzNum}" ]; then
                    hotfixBzNum="$1"
                fi
                ;;
        esac
        shift
    done
}

##
# Verify that all required options have been provided and that required
# files can be found and are readable.
#
# If a required option is missing, an error message is printed to
# stderr and this script is terminated.
#
# If a URL was provided for a file path, it will be downloaded. If a
# failure occurs during the download, an error message is printed to
# stderr and this script is terminated.
#
function validateConfiguration() {
    if [ -z "${hotfixNum}" ]; then
        echo >&2 "update_number argument is required. Use --help for usage help."
        exit 3
    fi

    if [ -z "${hotfixBzNum}" ]; then
        echo >&2 "update_id argument is required. Use --help for usage help."
        exit 3
    fi

    if [ -z "${serverArchive}" ]; then
        foundFile="$(readlink -f "$(ls jon-server-[0-9].[0-9].[0-9].GA.zip 2> /dev/null)" 2> /dev/null)"
        if [ ! -r  "${foundFile}" ]; then
            echo >&2 "Server archive file does not exist or cannot be read in location
[$(pwd)]."
            echo >&2 "Use --server-archive to specify an alternate location and file name."
            exit 2
        else
            serverArchive="${foundFile}"
        fi
    fi

    if [ -z "${pluginPackArchive}" ]; then
        foundFile="$(ls -1 jon-plugin-pack-*-[0-9].[0-9].[0-9].GA.zip 2> /dev/null | xargs -d '\n' readlink -f 2> /dev/null)"
        IFS=$'\n'
        for file in ${foundFile}; do
            if [ ! -r  "${file}" ]; then
                echo >&2 "Plug-in pack archive file ${file} cannot be read from location [$(pwd)]."
                echo >&2 "Use --plug-in-pack-archive to specify an alternate location and file name."
                exit 2
            else
                [ -z "${pluginPackArchive}" ] && pluginPackArchive="${file}" || pluginPackArchive="${pluginPackArchive}"$'\n'"${file}"
            fi
        done
        unset IFS
    fi

    if [ -z "${updateType}" ]; then
        if [ -n "${pluginPackArchive}" ]; then
            updateType="$(basename "${pluginPackArchive}")"
            updateType="${updateType/jon-plugin-pack-}"
            updateType="${updateType%%-[0-9]*}"
            ${isSilent} || echo "Update type will be [${updateType}]."
        else
            echo >&2 "Update type was not specified and could not be determined from update
archive file name. Please use --update-type option."
            exit 3
        fi
    fi

    if [ -n "${updateType}" ]; then
        case "$updateType" in
            'amq')
                pluginPackId=amq
                ;;
            'bpms')
                pluginPackId=bpms
                ;;
            'brms')
                pluginPackId=brms
                ;;
            'eap')
                pluginPackId=eap
                ;;
            'ews'|'jws')
                pluginPackId=ews
                ;;
            'fsw')
                pluginPackId=fsw
                ;;
            'fuse')
                pluginPackId=fuse
                ;;
            'jdg')
                pluginPackId=jdg
                ;;
            'jdv')
                pluginPackId=datavirtualization
                ;;
            'jpp'|'portal')
                pluginPackId=jpp
                ;;
            'soa')
                pluginPackId=soa
                ;;
            *)
                pluginPackId="${updateType}"
                echo >&2 "NOTICE: Update type of [${updateType}] may not be supported."
        esac
    else
        echo >&2 "Update type was not specified and could not be determined from update
archive file name. Please use --update-type option."
        exit 3
    fi

    if [ -n "${changesetFile}" ]; then
        if [[ ! "${changesetFile}" =~ https*://.* ]]; then
            changesetFile="$(readlink -f "${changesetFile}")"
            if [ ! -r  "${changesetFile}" ]; then
                echo >&2 "Change set file [${changesetFile}] does not exist or cannot be read."
                exit 2
            fi
        else
            newFile="$(mktemp)"
            ${isSilent} || echo "Downloading change set file..."
            if ! curl --fail --insecure --location --output "${newFile}" $(${isSilent} && echo "--silent") "${changesetFile}"; then
                echo >&2 "Download of change set file [${changesetFile}] has failed."
                rm -f "${newFile}"
                exit 2
            fi
            changesetFile="${newFile}"
            rmChangesetFile=true
        fi
    fi

    if [[ ! "${serverArchive}" =~ https*://.* ]]; then
        serverArchive="$(readlink -f "${serverArchive}")"
        if [ ! -r  "${serverArchive}" ]; then
            echo >&2 "Server archive file [${serverArchive}] does not exist or cannot be read."
            exit 2
        fi
    else
        newFile="$(mktemp)"
        ${isSilent} || echo "Downloading server archive file..."
        if ! curl --fail --insecure --location --output "${newFile}" $(${isSilent} && echo "--silent") "${serverArchive}"; then
            echo >&2 "Download of server archive file [${serverArchive}] has failed."
            rm -f "${newFile}"
            exit 2
        fi
        serverArchive="${newFile}"
        rmServerArchive=true
    fi

    if [[ ! "${pluginPackArchive}" =~ https*://.* ]]; then
        pluginPackArchive="$(readlink -f "${pluginPackArchive}")"
        if [ ! -r  "${pluginPackArchive}" ]; then
            echo >&2 "Plug-in pack archive file [${pluginPackArchive}] does not exist or cannot be read."
            exit 2
        fi
    else
        newFile="$(mktemp)"
        ${isSilent} || echo "Downloading plug-in pack archive file..."
        if ! curl --fail --insecure --location --output "${newFile}" $(${isSilent} && echo "--silent") "${pluginPackArchive}"; then
            echo >&2 "Download of server archive file [${pluginPackArchive}] has failed."
            rm -f "${newFile}"
            exit 2
        fi
        pluginPackArchive="${newFile}"
        rmPluginPackArchive=true
    fi

    if [ -n "${prevPluginPackArchive}" ]; then
        if [[ ! "${prevPluginPackArchive}" =~ https*://.* ]]; then
            prevPluginPackArchive="$(readlink -f "${prevPluginPackArchive}")"
            if [ ! -r  "${prevPluginPackArchive}" ]; then
                echo >&2 "Plug-in pack archive file [${prevPluginPackArchive}] does not exist or cannot be read."
                exit 2
            fi
        else
            newFile="$(mktemp)"
            ${isSilent} || echo "Downloading previous plug-in pack archive file..."
            if ! curl --fail --insecure --location --output "${newFile}" $(${isSilent} && echo "--silent") "${prevPluginPackArchive}"; then
                echo >&2 "Download of server archive file [${prevPluginPackArchive}] has failed."
                rm -f "${newFile}"
                exit 2
            fi
            prevPluginPackArchive="${newFile}"
            rmPrevPluginPackArchive=true
        fi
    fi
}

##
# Extract a ZIP archive to a specified directory.
#
# If an extraction failure occurs, the unzip utility will print an
# error message to stderr and return a non-zero exit code.
#
# $1 is the name and path of the file to be extracted.
# $2 is the path $1 is to be extracted to. If not specified, the
#    current work directory is used.
# $3 is the file(s) to be extracted from the zip.
#
function extractZip() {
    if [ $# -lt 1 ]; then
        echo >&2 "Missing parameter to function extractZip.
The name and path of the file to be extracted is require."
        return 1
    fi
    archive="$1"
    [ -z "$2" ] && dest="." || dest="$2"
    unzip -q "${archive}" $3 -d "${dest}"
}

parseArguments "$@"
validateConfiguration

failed=false
failedMsg=""

# Create a temporary directory to store our stuff in
_tmpDir="$(mktemp -d)"
mkdir -p "${_tmpDir}/patch"
mkdir -p "${_tmpDir}/new_plugins"
mkdir -p "${_tmpDir}/server"

# Extract the server archive
if ! extractZip "${serverArchive}" "${_tmpDir}/server"; then
    echo >&2 "Unable to extract server archive [${serverArchive}]."
    echo >&2 "Operation aborted."
    exit 4
fi

# Extract the plug-in pack archive
if ! extractZip "${pluginPackArchive}" "${_tmpDir}/new_plugins"; then
    echo >&2 "Unable to extract plug-in pack archive [${pluginPackArchive}]."
    echo >&2 "Operation aborted."
    exit 4
fi

# If a previous plug-in pack archive was specified, extract it
[ -n "${prevPluginPackArchive}" ] && {
    # Create a temporary scratch directory where we will put things together
    _tmpScratch="$(mktemp -d)"

    # Extract the previous plug-in pack archive
    if ! extractZip "${prevPluginPackArchive}" "${_tmpScratch}/patch"; then
        echo >&2 "Unable to extract previous plug-in pack archive [${prevPluginPackArchive}]."
        echo >&2 "Operation aborted."
        exit 4
    fi

    # If the previous plug-in pack did not use the plugins directory as its based,
    # iterate through all the extracted plug-ins and copy them over to the plugins directory
    for pluginDir in "${_tmpScratch}/patch"/jon-plugin-pack-*; do
        # Only create our destination plugins directory if the original directory really does exist
        if [ -e "${pluginDir}" ]; then
            # Create the root plugins directory for the update structure
            mkdir -p "${_tmpScratch}/patch/plugins"

            # Copy the plug-ins from the previous plug-in update to the new plugins directory
            cp -a "${pluginDir}"/. "${_tmpScratch}/patch/plugins"

            # Clean-up after ourselves
            rm -rf "${pluginDir}"
        fi
    done

    # Now copy/move the contents of our scratch patch directory to its semi-final resting place
    cp -a "${_tmpScratch}/patch/." "${_tmpDir}/patch"
    rm -rf "${_tmpScratch}"
}

# Remove the previous patches .patched directory as we will replace it in our new update
rm -rf "${_tmpDir}/patch/.patched"

# Create a temporary scratch directory where we will put things together
_tmpScratch="$(mktemp -d)"
mkdir -p "${_tmpScratch}"'/plugins'

# Read through the change set file and add/delete the changed files from the build to scratch space
while read file; do
    archive=""
    fileLocation=""
    if [ -n "${file}" ]; then
        if [[ "${file}" = "-"* ]]; then
            # we delete the file from our patches plugins directory
            file="${file#?}"
            if [ ! -e "${_tmpDir}/patch/plugins/${file}" ]; then
                failed=true
                failedMsg="${failedMsg}"$'\n'"Failed to delete removed file [${file}] as it did not exist."
            else
                rm -rf "${_tmpDir}/patch/plugins/${file}"
            fi
        else
            # trim leading plus if it is there
            if [[ "${file}" = "+"* ]]; then
                file="${file#?}"
            fi

            if [[ "${file}" =~ .*\!/.* ]]; then
                archive="$(expr "$file" : '\(.*\)!/.*')"
                file="$(expr "$file" : '.*!/\(.*\)')"
                # check to see if it is a file or URL
                if [[ "${archive}" =~ https*://.* ]]; then
                    newFile="$(mktemp)"
                    ${isSilent} || echo "Downloading additional plug-in archive [${archive}] referenced in change set file..."
                    if ! curl --fail --insecure --location --output "${newFile}" $(${isSilent} && echo "--silent") "${archive}"; then
                        failed=true
                        failedMsg="${failedMsg}"$'\n'"Failed to copy new file [${file}] as the archive file [${archive}] failed to download."
                    fi
                    archive="${newFile}"
                    rmArchiveFile=true
                else
                    rmArchiveFile=false
                fi
                archive="$(readlink -f "${archive}")"
                if [ ! -r  "${archive}" ]; then
                    failed=true
                    failedMsg="${failedMsg}"$'\n'"Failed to copy new file [${file}] as the archive file [${archive}] does not exist."
                else
                    fileLocation="$(mktemp -d "${_tmpDir}/archiveXXXXXXXX")"
                    if [[ "${file}" = "/"* ]]; then
                        fileToExtract="${file#?}"
                    else
                        fileToExtract="${file}"
                    fi

                    if extractZip "${archive}" "${fileLocation}" "${fileToExtract}" 2>/dev/null; then
                        file="${fileToExtract}"
                    elif extractZip "${archive}" "${fileLocation}" "plugins/${fileToExtract}" 2>/dev/null; then
                        file="plugins/${fileToExtract}"
                    elif extractZip "${archive}" "${fileLocation}" "$(basename "${archive}" .zip)/${fileToExtract}" 2>/dev/null; then
                        file="$(basename "${archive}" .zip)/${fileToExtract}"
                    else
                        failed=true
                        failedMsg="${failedMsg}"$'\n'"Failed to copy new file [${file}] as it could not be found in archive file [${archive}]."
                    fi
                    ${rmArchiveFile} && rm -f "${rmArchiveFile}"
                fi
            fi

            # Set file's location
            if [ -z "${fileLocation}" ]; then
                if [ -e "${_tmpDir}/new_plugins/plugins/${file}" ]; then
                    fileLocation="${_tmpDir}/new_plugins/plugins"
                elif [ -e "${_tmpDir}/new_plugins/jon-plugin-pack-"*".GA/${file}" ]; then
                    fileLocation=$(eval echo ${_tmpDir}/new_plugins/jon-plugin-pack-*.GA)
                fi
            fi

            # Change into the directory containing the plug-in file
            pushd "${fileLocation}/$(dirname "${file}")" >/dev/null

            # we are adding/replacing a file
            # we do this because of strange and random build issues
            chmod 664 "$(basename "${file}")"

            # Copy the change set file along with its parent path to the scratch space
            cp --parents -a "$(basename "${file}")" "${_tmpScratch}/plugins"

            # Check to see if the file made it
            if [ ! -e "${_tmpScratch}/plugins/$(basename "${file}")" ]; then
                failed=true
                failedMsg="${failedMsg}"$'\n'"Failed to copy new file [${file}] as it does not exist."
            fi
            popd  >/dev/null
        fi
    fi
done <"${changesetFile}"

# Merge the files/directories into the patch
cp -a "${_tmpScratch}/." "${_tmpDir}/patch"

# Clean-up after ourselves
rm -r "${_tmpScratch}"

# Set the location of server JARs that contain version and build info
if [ "${pkgVersion}" = "3.0" ]; then
    _rhqEarPath="jbossas/server/default/deploy/rhq.ear.rej"
    _rhqServerJarPath="${_rhqEarPath}/rhq-enterprise-server-ejb3.jar"
fi
if [ "${pkgVersion}" = "3.2" ]; then
    _rhqEarPath="modules/org/rhq/server-startup/main/deployments/rhq.ear"
    _rhqServerJarPath="${_rhqEarPath}/rhq-server.jar"
fi

# Retrieve version info from the server archive
pushd "${_tmpDir}/server/jon-server-"*".GA" >/dev/null
JONVersion="$(grep '^version=.*$' "./${_rhqServerJarPath}/org/rhq/enterprise/server/core/ProductInfo.properties" | awk -F= '{print $2}')"
BuildId="$(grep '^buildNumber=.*$' "./${_rhqServerJarPath}/org/rhq/enterprise/server/core/ProductInfo.properties" | awk -F= '{print $2}' | awk '{sub(/\\/,"");print }')"
BuildTime="$(TZ="GMT" date -d "$(head -n1 "./${_rhqServerJarPath}/org/rhq/enterprise/server/core/ProductInfo.properties" | awk -F# '{print $2}')" +"%m/%d/%y %I:%M %p %Z")"
popd >/dev/null

# Print version information
${isSilent} || {
    echo ""
    echo " Plug-in Pack ID: ${pluginPackId}"
    echo "JBoss ON Version: ${JONVersion}"
    echo "   Update Number: ${hotfixNum}"
}

# Determine update/file name
if [ "${pkgVersion}" = "3.0" ]; then
    hotfixName="jon-plugin-pack-${pluginPackId}-${JONVersion}-hotfix-${hotfixNum}"
else
    hotfixName="jon-plugin-pack-${pluginPackId}-${JONVersion}-update-${hotfixNum}"
fi

# Change into our new patch structure
pushd "${_tmpDir}/patch" >/dev/null

# Generate checksum list for contents of patch
JONHotfixContentMD5s="$(find -type f | sort | xargs -I{} md5sum "{}")"

# Read configuration
[ -f "${SCRIPT_HOME}/pluginpack-update.conf" ] && . "${SCRIPT_HOME}/pluginpack-update.conf"

# Set supersedes text if a previous update was specified
[ -n "${prevPluginPackArchive}" ] && superseedsText="$(basename "${prevPluginPackArchive//.zip}")" || superseedsText="N/A"

# Set dependency text
dependenciesText="N/A"
if [[ "${JONVersion}" == 3.3.* ]]; then
    dependenciesText="Red Hat JBoss Operations Network 3.3"
elif [[ "${JONVersion}" == 3.2.* ]]; then
    dependenciesText="Red Hat JBoss Operations Network 3.2"
elif [[ "${JONVersion}" == 3.1.2 ]]; then
    dependenciesText="Red Hat JBoss Operations Network 3.1.2"
elif [[ "${JONVersion}" == 3.1.1 ]]; then
    dependenciesText="Red Hat JBoss Operations Network 3.1.1"
fi

# Set portal/Doc Text field text
portalDocText="$(cat <<EOF
PATCH NAME:
    ${hotfixName}
PRODUCT NAME:
$(IFS=''; echo "${productList[${pluginPackId}-${JONVersion}]}" | while read product; do
    echo "    ${product}"
done)
VERSION:
    ${JONVersion//.GA}
SHORT DESCRIPTION:
    ${patchShortDescList[${pluginPackId}-${JONVersion}]]}
LONG DESCRIPTION:
$(IFS=''; echo "${patchLongDescList[${JONVersion}]]}" | while read line; do
    echo "    ${line}"
done)
MANUAL INSTALL INSTRUCTIONS:
$(IFS=''; echo "${patchInstructionList[${JONVersion}]}" | while read line; do
    echo "    ${line}"
done)
COMPATIBILITY:
    N/A
DEPENDENCIES:
    ${dependenciesText}
SUPERSEDES:
    ${superseedsText}
SUPERSEDED BY:
    N/A
CREATOR:
    $(finger -m ${USERNAME} | head -n1 | awk -F'Name: ' '{print $2}')
EOF
)"

# Create .patched descriptor text
if [ "${pkgVersion}" = "3.0" -o "${pkgVersion}" = "3.2" ]; then
    patchREADMEName="${hotfixName}"
    patchREADME='Name:           '"${hotfixName}"'
ID:             BZ'"${hotfixBzNum}"'
Version:        '"${JONVersion}"'
Build ID:       '"${BuildId}"'
Build Time:     '"${BuildTime}"'

MD5:
'"${JONHotfixContentMD5s}"
else
    patchREADMEName="README-${hotfixName}"
    patchREADME="${portalDocText}"
fi

# Create .patched directory and file
_tmpScratch="$(mktemp -d)"
mkdir -p .patched
echo "${patchREADME}" >"${_tmpScratch}/${patchREADMEName}"
mv "${_tmpScratch}/${patchREADMEName}" "${_tmpDir}/patch/.patched"
rm -r "${_tmpScratch}"

popd >/dev/null

# Create the new update archive
pushd "${_tmpDir}/patch" >/dev/null
rm -f "${_tmpDir}/${hotfixName}.zip"
zip -qr "${_tmpDir}/${hotfixName}.zip" "."
popd >/dev/null

# Print out various information about the patch including the portal/Doc Text field text
${isSilent} || {
    echo ""
    echo "======================================================================"
    echo " Patch File Archive Contents "
    echo "======================================================================"
    echo ""
    pushd "${_tmpDir}" >/dev/null
    unzip -l "${hotfixName}.zip"
    popd >/dev/null
}
${isSilent} || {
    echo ""
    echo "======================================================================"
    echo " Contents of .patched/${patchREADMEName} "
    echo "======================================================================"
    echo ""
    cat "${_tmpDir}/patch/.patched/${patchREADMEName}"
}
${isSilent} || {
    echo ""
    echo "======================================================================"
    echo " BZ Doc Text Field / Portal Description "
    echo "======================================================================"
    echo ""
    echo "${portalDocText}"
}
${isSilent} || {
    echo ""
    echo "======================================================================"
    echo " File Details / Checksums "
    echo "======================================================================"
    echo ""
    echo "# Name:           ${hotfixName}"
    echo "# ID:             BZ${hotfixBzNum}"
    echo "# Version:        ${JONVersion}"
    echo "# Build ID:       ${BuildId}"
    echo "# Build Time:     ${BuildTime}"
    echo "# "
    echo "# SHA256:"
    (cd ${_tmpDir} && sha256sum "${hotfixName}.zip")
    echo "# "
    echo "# MD5:"
    (cd ${_tmpDir} && md5sum "${hotfixName}.zip")
    echo "# "
    echo "# Contents MD5:"
    echo "${JONHotfixContentMD5s}"
    echo ""
}

# Place the update archive in the current work directory
mv "${_tmpDir}/${hotfixName}.zip" .

# Clean up all the temp stuff
rm -r "${_tmpDir}"

# Remove downloaded files
if ${rmChangesetFile}; then
    rm -f "${changesetFile}"
fi
if ${rmServerArchive}; then
    rm -f "${serverArchive}"
fi
if ${rmPluginPackArchive}; then
    rm -f "${pluginPackArchive}"
fi
if ${rmPrevPluginPackArchive}; then
    rm -f "${prevPluginPackArchive}"
fi

# If anything failed, report it and exit with non-zero exit code
if $failed; then
    echo >&2 "The plug-in pack may be incomplete as one or more failures occurred:"
    echo >&2 "${failedMsg}"
    exit 1
fi
