#!/bin/bash
#
#   makePackage - Create Installation Packages
#
#   This script creates ....
#
#   ${BLD_PRODUCT}-bin-{version}-{build}-{OS}-{ARCH}.{FMT}.tar.gz
#   ${BLD_PRODUCT}-dev-{version}-{build}.{FMT}.tar.gz
#   ${BLD_PRODUCT}-doc-{version}-{build}.{FMT}.tar.gz
#   ${BLD_PRODUCT}-src-{version}-{build}.{FMT}.tar.gz
#
################################################################################
#
#   Copyright (c) Embedthis Software LLC, 2003-2009. All Rights Reserved.
#   The latest version of this code is available at http://www.embedthis.com
#
#   This software is open source; you can redistribute it and/or modify it 
#   under the terms of the GNU General Public License as published by the 
#   Free Software Foundation; either version 2 of the License, or (at your 
#   option) any later version.
#
#   This program is distributed WITHOUT ANY WARRANTY; without even the 
#   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
#   See the GNU General Public License for more details at:
#   http://www.embedthis.com/downloads/gplLicense.html
#   
#   This General Public License does NOT permit incorporating this software 
#   into proprietary programs. If you are unable to comply with the GPL, a 
#   commercial license for this software and support services are available
#   from Embedthis Software at http://www.embedthis.com
#
################################################################################

setup() {

    umask 022

    BLD_DATE=`date '+%c'`

    #
    #   If ROOT_DIR is set, it defines a ROOT directory under which the installation will occurr.
    #
    ORIGINAL_ROOT_DIR="$ROOT_DIR"
    ROOT_DIR=${ROOT_DIR:-${BLD_TOP}/.tmp}
    ROOT_DIR=`${BLD_TOP}/build/bin/getpath -a "${ROOT_DIR}"`
    mkdir -p ${ROOT_DIR}

    cd ${BLD_TOP}
    BLD_TOP=.
    HOME=`pwd`

    . ${BLD_TOP}/build/buildConfig.sh

    if [ "${BLD_CROSS}" = 1 ] ; then
        BUILDING_CROSS=1
        . ./build/buildConfig.sh
    fi

    . ${BLD_TOP}/build/bin/makePackage.common

    if [ $BLD_BUILD_OS = LINUX -a `id -u` != 0 ] ; then
        echo -e "\nWARNING: Non-root package. Installed files will be owned by `id -nu`\n"
    fi

    set -e
    echo -e "\n  #"
    echo -e "  #  Building \"${BLD_NAME} ${BLD_VERSION}-${BLD_NUMBER}\"\n  #\n"
    # set | grep BLD_ | sort | sed -e 's/^/  #     /'

    preparePrefixes

    echo -e "  #\n  #  Clean the image area ...\n  #"
    echo "  rm -fr ${BLD_TOP}/releases/${BLD_PRODUCT}-*"
    ${RM} -fr ${BLD_TOP}/releases/${BLD_PRODUCT}-*
    echo "  rm -fr ${BLD_TOP}/releases/md5-${BLD_PRODUCT}-*"
    ${RM} -fr ${BLD_TOP}/releases/md5-${BLD_PRODUCT}-*

    set +e
    type pp >/dev/null 2>&1
    if [ $? != 0 -a -f ${ABS_BLD_TOP}/embedthis ]
    then
        echo "Can't find pp. This is required when making Embedthis packages."
        exit 2
    fi
    set -e
}


patchSource() {
    local f

    echo -en "\n  #\n  #  "
    echo -e "Patch copyrights and select required features ...\n  #"

    #
    #   Patch copyrights
    #
    if [ -f "${BLD_SRC_PREFIX}" ] ; then
        cd "${BLD_SRC_PREFIX}"
        (
            find . -name '*.h'
            find . -name '*.c'
            find . -name '*.js'
            find . -name '*.cpp'
        ) | ${ABS_BLD_TOOLS_DIR}/incPatch -l ${ABS_BLD_TOP}/build/copyrights/${BLD_LICENSE}

        #
        #   Strip out unwanted features
        #
        (
            find . -name '*.h'
            find . -name '*.c'
            find . -name '*.cpp'
        ) | while read f
        do
            ${ABS_BLD_TOOLS_DIR}/defeature ${ABS_BLD_TOP}/build/buildConfig.sh $f
        done
        cd ${HOME}
    fi
}


createFileList() {
    local prev

    prev=`pwd`
    list=`getpath -a "$1/fileList.txt"`
    cd "$2" >/dev/null
    find . -type f -print > "${list}"
    find . -type l -print >> "${list}"
    [ $BLD_HOST_OS != WIN ] && chgrp 0 "${list}"
    cd "$prev" >/dev/null
}


createPackageName() {
    echo ${1}-${BLD_VERSION}-${BLD_NUMBER}-${BLD_HOST_DIST}-${BLD_HOST_OS}-${BLD_HOST_CPU}
}


createArchives() {
    local base dir name listLoc fromFiles

    for suffix in bin dev src ; do
        echo -en "\n  #\n  #  "

        name="${BLD_PRODUCT}-${suffix}"
        dir=`echo "${suffix}" | tr '[a-z]' '[A-Z]'`

        echo -e "Create raw tar images for: ${ROOT_DIR}/${dir} ...\n  #"

        case $suffix in
        bin)
            listLoc="${BLD_PREFIX}"
            ;;
        dev)
            listLoc="${BLD_INC_PREFIX}"
            ;;
        src)
            listLoc="${BLD_SRC_PREFIX}"
            ;;
        esac

        [ ! -d "${ROOT_DIR}/${dir}" ] && continue

        #
        #   Treat src specially as we want the source to be directly under the top directory.
        #
        if [ "$suffix" = "src" ] ; then

            file=`echo ${BLD_PRODUCT}-src-${BLD_VERSION}-${BLD_NUMBER}.tar`
            file="${ROOT_DIR}/$file"
            ${RM} -f "${file}" "${file}.gz"
            [ $BLD_HOST_OS = WIN ] && file=`cygpath "${file}"`

            #
            #   cd SRC/usr/src/product-version
            #
            cd "${BLD_SRC_PREFIX}/.." >/dev/null
            base=`basename "${BLD_SRC_PREFIX}"`
            dir=./${base}

            createFileList "${BLD_SRC_PREFIX}" "${BLD_SRC_PREFIX}/.."

            #
            #   Important: must not include directories in the tar archive.
            #   Must include the top level directory (avoids tar bombs)
            #   Must include symlinks.
            #
            fromFiles=/tmp/tar.list$$
            find $dir -type f -print > $fromFiles
            find $dir -type l -print >>$fromFiles

            ${RM} -f ${file} ${file}.gz

            echo "  tar -cf ${file} --files-from=$fromFiles"
            tar -cf ${file} --files-from=$fromFiles
            gzip ${file}

            echo -en "\n  #\n  #  "
            echo -e "Create zip images for the src distribution ...\n  #"

            file=`echo ${BLD_PRODUCT}-src-${BLD_VERSION}-${BLD_NUMBER}.zip`
            file="${ROOT_DIR}/$file"
            [ $BLD_HOST_OS = WIN ] && file=`cygpath "${file}"`
            ${RM} -f "${file}"
            echo "  cat fileList.txt | zip -q ${file} -@"
            cat "$dir/fileList.txt" | zip -q "${file}" -@
            cd $HOME >/dev/null

        else
            file=`createPackageName $name`.tar
            ${RM} -f "${ROOT_DIR}/${file}" "${ROOT_DIR}/${file}.gz"

            createFileList "$listLoc" "${ROOT_DIR}/${dir}"

            #
            #   Important: must not include directories in the tar archive.
            #   Must include the top level directory (avoids tar bombs). Must include symlinks.
            #
            cd ${ROOT_DIR} >/dev/null
            fromFiles=/tmp/tar.list$$
            find $dir -type f -print > $fromFiles
            find $dir -type l -print >>$fromFiles

            echo "  tar -cf ${file} --files-from=${fromFiles}"
            tar -cf ${file} --files-from=${fromFiles}
            gzip ${file}

            if [ "$suffix" = "src" ] ; then
                echo -en "\n  #\n  # "
                echo -e "Create zip images for the src distribution ...\n  #"
                echo "  cat fileList.txt | zip -q ${file} -@"
                cat "$dir/fileList.txt" | zip -q "${ROOT_DIR}/${file}" -@
            fi
            cd $HOME >/dev/null
        fi
        rm -f /tmp/tar.list$$
    done
}


createScripts() {

    cp package/install.sh ${ROOT_DIR}/install
    cp package/uninstall.sh ${ROOT_DIR}/uninstall

    cp doc/licenses/LICENSE.TXT ${ROOT_DIR}
    if [ -f package/${BLD_HOST_OS}/README.TXT ] ; then
        cp package/${BLD_HOST_OS}/README.TXT ${ROOT_DIR}
    fi
    if [ -f doc/product/README.TXT ] ; then
        cp doc/product/README.TXT ${ROOT_DIR}
    fi

    cd ${ROOT_DIR} >/dev/null
    patchFile install uninstall README.TXT LICENSE.TXT
    chmod 755 install uninstall
    chmod 644 README.TXT LICENSE.TXT
    if [ $BLD_HOST_OS = WIN ] ; then
        if type dos2unix >/dev/null 2>&1 ; then
            dos2unix install >/dev/null 2>&1
            dos2unix uninstall >/dev/null 2>&1
            dos2unix README.TXT  >/dev/null 2>&1
            dos2unix LICENSE.TXT >/dev/null 2>&1
        fi
    fi
    cd ${HOME} >/dev/null
}


#
#   Checksum a file (wildcards okay)
#
sum() {
    local file dir base

    file="$1"
    base=${file##*/}                # basename
    dir=${file%/*}                  # dirname

    cd "$dir" >/dev/null
    echo "  md5sum ${base} md5-${base}.txt"
    md5sum "${base}" | awk '{ print $1 }' > "${dir}/md5-${base}.txt"
    chmod 755 "${dir}/md5-${base}.txt"
    chown `id -ru` "${dir}/md5-${base}.txt"
    cd $HOME >/dev/null
}


cleanup() {
    echo -e "\n  #\n  # Done \n  #\n"

    if [ $BLD_BUILD_OS = LINUX -a `id -u` != 0 ] ; then
        echo -e "\nWARNING: Non-root package. Installed files will be owned by `id -nu`\n"
    fi
    # ${RM} -rf ${ROOT_DIR}
}


createPlatformPackages() {
    
    set +e

    . ${BLD_TOOLS_DIR}/makeTarPackage

    if [ -x "$BLD_BUILD_PKG" ] ; then
        . ${BLD_TOOLS_DIR}/makeWinPackage
    fi

    if [ $BLD_HOST_OS = MACOSX ] ; then
        . ${BLD_TOOLS_DIR}/makeDmgPackage

    elif [ $BLD_HOST_OS = LINUX ] ; then
        if type dpkg-buildpackage >/dev/null 2>&1 ; then
            . ${BLD_TOOLS_DIR}/makeDebPackage
        fi

        if type rpmbuild >/dev/null 2>&1 ; then
            if [ -f /etc/redhat-release -o -f /etc/SuSE-release ] ; then
                . ${BLD_TOOLS_DIR}/makeRPMPackage
            fi
        fi
    fi
    set -e
}


#
#   Create the default install envelope
#
createEnvelopes() {

    local baseName name env fmt files

    if [ $BLD_HOST_OS = MACOSX ] ; then
        return
    fi

    echo -ne "\n  #\n  # "
    echo -e "Create envelopes ...\n  #"

    mkdir -p ${ABS_BLD_TOP}/releases

    #
    #   Envelope the platform packages with readme and optionally install/uninstall scripts.
    #   Don't do for MAC OS X dmg formats.
    #
    baseName="${BLD_PRODUCT}-${BLD_VERSION}-${BLD_NUMBER}-${BLD_HOST_DIST}-${BLD_HOST_OS}-${BLD_HOST_CPU}"
    cd ${ROOT_DIR} >/dev/null
    count=0
    for fmt in deb rpm tar exe ; do

        if ! ls *.${fmt} >/dev/null 2>&1 ; then
            continue
        fi

        name="${baseName}.${fmt}"

        if [ $fmt = exe ] ; then
            env=${ROOT_DIR}/$name.zip
            ${RM} -f $zip 
            echo "  ls -1 README.TXT LICENSE.TXT *.$fmt | grep -v "${BLD_PRODUCT}-src" | \\"
            echo "    zip -q ${env} -@"
            ls -1 README.TXT LICENSE.TXT *.$fmt | grep -v "${BLD_PRODUCT}-src" | zip -q ${env} -@
            ls -1 README.TXT LICENSE.TXT *.$fmt | zip -q "${env}" -@
        else
            env=${ROOT_DIR}/$name.tar
            ${RM} -f $env ${env}.gz
            files="*.$fmt"
            srcPkg=`createPackageName ${BLD_PRODUCT}-src`.${fmt}
            files=`echo $files | sed "s^$srcPkg^^"`
            echo "  tar -cf `basename ${env}` README.TXT LICENSE.TXT install uninstall $files"
            tar -cf ${env} README.TXT LICENSE.TXT install uninstall $files
            echo "  gzip ${env}"
            gzip ${env}
        fi
        count=`expr $count + 1`
    done
    cd ${HOME} >/dev/null

    if [ "$count" = 0 ] ; then
        # TODO - temporary until we have a mac installation
        if [ $BLD_BUILD_OS != MACOSX ] ; then
            echo "Could not find any packages to envelope in $ROOT_DIR"
            echo "Using base name $baseName"
            exit 255
        fi
    fi
}


copyImages() {
    local ext file zip

    for ext in dmg deb rpm gz zip ; do
        if ls ${ROOT_DIR}/${BLD_PRODUCT}*${ext} >/dev/null 2>&1 ; then
            cp ${ROOT_DIR}/${BLD_PRODUCT}*${ext} ${ABS_BLD_TOP}/releases
        fi
    done
    chown `id -ru` ${ABS_BLD_TOP}/releases/${BLD_PRODUCT}-*
}


createChecksums() {
    local file

    if ls ${ABS_BLD_TOP}/releases/${BLD_PRODUCT}-* >/dev/null 2>&1
    then
        echo -ne "\n  #\n  # "
        echo -e "Create checksums ...\n  #"
        ls ${ABS_BLD_TOP}/releases/${BLD_PRODUCT}-* | \
        while read file ; do
            sum "${file}"
        done
    fi
}


#
#   Main
#
if [ "$DRY_RUN" = 1 ] ; then
    echo -e "\nSkip packaging because DRY_RUN is set\n"
    exit 0
fi

PACKS=${*-"binary source"}

setup
patchSource
createArchives
createScripts
createPlatformPackages
createEnvelopes
copyImages
createChecksums
cleanup
