#!/bin/bash

Action=""
Project=""
BinDir=""
DataDir=""
SysConfDir=""
LocalStateDir=""

##--------------- Add calls to your upgrade functions in here -------------
##
##  Add a function call to upgrade your project configuration files in
##  this case statement. Put the relevant shell script inside that function
##  in the section immediately following the case statement.
##
###########################################################################

SipxUpgrade() {
    case $Project in

        ## Upgrade section of sipXcommserverLib - add upgrade call here
        ###################################################################
        sipxcommserverlib)
            UpgradeCommserver
            ;;

        ## Upgrade section of sipXpublisher - add upgrade call here
        ###################################################################
        sipxpublisher)
            UpgradeSubscriptions
            ;;

        ## Upgrade section of sipXregistry - add upgrade call here
        ###################################################################
        sipxregistry)
            UpgradeRegistry
            ;;

        ## Upgrade section of sipXproxy - add upgrade call here
        ###################################################################
        sipxproxy)
            UpgradeProxy
            ;;

        ## Upgrade section of sipXconfig - add upgrade call here
        ###################################################################
        sipxconfig)
            UpgradeConfigServer
            ;;

        ## Upgrade section of sipXvxml - add upgrade call here
        ###################################################################
        sipxvxml)
            ;;

        ## Upgrade section of sipXpbx - add upgrade call here
        ###################################################################
        sipxpbx)
            UpgradePbx
            ;;

        ## We shouldn't be here
        *)
            echo >&2 "Unknown project name: $Project"
            exit 1
            ;;
    esac
}

###########################################################################
## Add your upgrade functions in here
##
##    The following variables are available:
##
##          $Version   a version string of a previously installed project 
##                     RPM in the format x.y.z, or the null string,
##                     if there was no previously installed project
##          $ShortVersion  a version string in the format x.y
##          $Major     Major version number x of installed RPM
##          $Minor     Minor version number y of installed RPM
##          $Sub       Version number z of installed RPM
##          $Rel       Release number of installed RPM
##
##          $BinDir          %{_bindir} if passed in with --bdir
##          $DataDir         %{_datadir} if passed in with --ddir
##          $SysConfDir      %{_sysconfdir} if passed in with --cdir
##          $LocalStateDir   %{_localstatedir} if passed in with --sdir
###########################################################################

##########################
## Upgrade the commserver lib 
##########################
UpgradeCommserver() {
    case $Version in
        2.8* | 2.6*)
            # add the sipXpark specific variables to an existing modified 2.6.x or 2.8.x config.defs file
            if test -r ${SysConfDir}/sipxpbx/config.defs.rpmnew
            then
                cp ${SysConfDir}/sipxpbx/config.defs ${SysConfDir}/sipxpbx/config.defs.OLD
                sed -e '$a\\nORBIT_SERVER_ADDR=${MY_IP_ADDR}\nORBIT_SERVER_SIP_PORT=5120\nORBIT_SERVER_SIP_SECURE_PORT=5121\nORBIT_SERVER_SIP_SRV_OR_HOSTPORT=${ORBIT_SERVER_ADDR}:${ORBIT_SERVER_SIP_PORT}' ${SysConfDir}/sipxpbx/config.defs.OLD > ${SysConfDir}/sipxpbx/config.defs
                rm -f ${SysConfDir}/sipxpbx/config.defs.rpmnew
            fi

            CAdir=@SIPX_CONFDIR@/ssl/authorities
            authorities=`find ${CAdir} \( -name \*.crt -o -name \*.crl -o -name \*.pem \) 2>/dev/null`
            if [ -z "${authorities}" ]
            then
                cat 1>&2 <<EOF

    No certificate authorities found in '${CAdir}'

       If you used a self-signed certificate, you need to copy
       the ca.crt file generated by gen-ssl-keys.sh into that
       directory.

       If you are using another certificate authority, you need
       to copy the authority certificate for it (in PEM format) 
       into that directory as a file with a '.crt' suffix.

    In either case, then (as root) run:

        @bindir@/ssl-cert/ca_rehash 

EOF
            fi
            ;;

        2.9*)
            ;;

        '')
            # New installation needs no upgrade.
            ;;

        *)
            echo >&2 "Unknown old version: $Version"
            exit 1
            ;;
    esac
}

##########################
## Upgrade the registry 
##########################
UpgradeRegistry() {
   case $Version in
       2.6*)
           UpgradeRegistry2_6To2_8
           UpgradeRegistry2_8To3_0
           ;;

       2.8*)
           UpgradeRegistry2_8To3_0
           ;;

       2.9* | 3.0*)
           ;;

       '')
           # New installation needs no upgrade.
           ;;

       *)
           echo >&2 "Unknown old version: $Version"
           exit 1
           ;;
    esac
}

# Upgrade the registry from 2.6 to 2.8.
UpgradeRegistry2_6To2_8() {
    # add the namespace to an existing 2.6.x huntgroup file
    f=${LocalStateDir}/sipxdata/sipdb/huntgroup.xml
    if test -r $f
    then
        cp $f $f.OLD
        sed 's|<items type="huntgroup">|<items type="huntgroup" xmlns="http://www.sipfoundry.org/sipX/schema/xml/huntgroup-00-00">|' $f.OLD > $f
    fi

    # add the namespace to an existing 2.6.x alias file
    f=${LocalStateDir}/sipxdata/sipdb/alias.xml
    if test -r $f
    then
        cp $f $f.OLD
        sed 's|<items type="alias">|<items type="alias" xmlns="http://www.sipfoundry.org/sipX/schema/xml/alias-00-00">|' $f.OLD > $f
    fi

    # add the namespace to an existing 2.6.x mappingrules or fallbackrules file
    for f in ${SysConfDir}/sipxpbx/mappingrules.xml.in \
             ${SysConfDir}/sipxpbx/fallbackrules.xml.in
    do 
        if test -r $f
        then
            cp $f $f.OLD
            sed 's|<mappings>|<mappings xmlns="http://www.sipfoundry.org/sipX/schema/xml/urlmap-00-00">|' $f.OLD > $f
        fi
    done
}

# Upgrade the registry from 2.8 to 3.0.
UpgradeRegistry2_8To3_0() {
    # Add config lines to support new features.
    AddConfigLine ${SysConfDir}/sipxpbx/registrar-config.in \
        SIP_REGISTRAR_GLOBAL_CALL_PICKUP_CODE ''
    AddConfigLine ${SysConfDir}/sipxpbx/registrar-config.in \
        SIP_REGISTRAR_DIRECTED_CALL_PICKUP_CODE '*78'
    AddConfigLine ${SysConfDir}/sipxpbx/registrar-config.in \
        SIP_REGISTRAR_CALL_RETRIEVE_CODE '*4'
    AddConfigLine ${SysConfDir}/sipxpbx/registrar-config.in \
        SIP_REGISTRAR_CALL_PICKUP_WAIT 2.0
    AddConfigLine ${SysConfDir}/sipxpbx/registrar-config.in \
        SIP_REGISTRAR_PARK_SERVER '${ORBIT_SERVER_SIP_SRV_OR_HOSTPORT}'
    # Add plugin for Implied MWI
    AddConfigLine ${SysConfDir}/sipxpbx/registrar-config.in \
        SIP_REGISTRAR_HOOK_LIBRARY.MWI '@SIPX_LIBDIR@/libRegistrarImpliedMWI.so'
    # Convert hardcoded MWI specifiers to use the plugin
    perl -pi -e 's/SIP_REGISTRAR_MWI_SUBSCRIBE/SIP_REGISTRAR.MWI.UA/' \
         ${SysConfDir}/sipxpbx/registrar-config.in
}

##########################
## Upgrade the proxy 
##########################
UpgradeProxy() {
    case $Version in
        2.6*)
            # add the namespace to an existing 2.6.x authrules file
            f=${SysConfDir}/sipxpbx/authrules.xml.in
            if test -r $f
            then
                cp $f $f.OLD
                sed 's|<mappings>|<mappings xmlns="http://www.sipfoundry.org/sipX/schema/xml/urlauth-00-00">|' $f.OLD > $f
            fi
            ;;
        2.8* | 2.9*)
            ;;

        '')
            # New installation needs no upgrade.
            ;;

        *)
            echo >&2 "Unknown old version: $Version"
            exit 1
            ;;
    esac
}
 
##########################
## Upgrade the subscription database
##########################
UpgradeSubscriptions() {
   case $Version in
       2.6*)
           # remove file column, add id column
           if test -r ${LocalStateDir}/sipxdata/sipdb/subscription.xml
           then
               perl -pi -e 's|<file>[^<]*</file>|<id></id>|' ${LocalStateDir}/sipxdata/sipdb/subscription.xml
           fi
           ;;

        2.8* | 2.9*)
           ;;

        '')
            # New installation needs no upgrade.
            ;;

        *)
           echo >&2 "Unknown old version: $Version"
           exit 1
           ;;
    esac
}

##########################
## Upgrade the PBX 
##########################
UpgradePbx() {
    case $Version in
        2.6*)
            # add the <ivr-prompt-url> field to an existing modified 2.6.x voicemail.xml.in file
            if test -r ${SysConfDir}/sipxpbx/voicemail.xml.in.rpmnew
            then
                cp ${SysConfDir}/sipxpbx/voicemail.xml.in ${SysConfDir}/sipxpbx/voicemail.xml.in.OLD
                sed -e '82d;93a\ ' -e '93a\ \ \ \ \ \ \ \ <!--' -e '93a\ \ \ \ \ \ \ \ \ \ \ \ IVR prompt base URL - used by VXML interpreter for' -e '93a\ \ \ \ \ \ \ \ \ \ \ \ retrieving standard prompts.' -e '93a\ \ \ \ \ \ \ \ -->' -e '93a\ \ \ \ \ \ \ \ <ivr-prompt-url>file:///usr/share/www/doc</ivr-prompt-url>' ${SysConfDir}/sipxpbx/voicemail.xml.in.OLD > ${SysConfDir}/sipxpbx/voicemail.xml.in
                rm -f ${SysConfDir}/sipxpbx/voicemail.xml.in.rpmnew
            fi

            # if "customautoattendant.wav" exists, rename it to "customautoattendant-internal.wav"
            if test -r ${LocalStateDir}/sipxdata/mediaserver/data/prompts/customautoattendant.wav
            then
                mv ${LocalStateDir}/sipxdata/mediaserver/data/prompts/customautoattendant.wav ${LocalStateDir}/sipxdata/mediaserver/data/prompts/customautoattendant-internal.wav
            fi
            ;;

        2.8* | 2.9*)
            ;;

        '')
            # New installation needs no upgrade.
            ;;

        *)
            echo >&2 "Unknown old version: $Version"
            exit 1
            ;;
    esac
}


##########################
## Upgrade the ConfigServer
##########################
UpgradeConfigServer() {
    MergeRpmConfigFile "${SysConfDir}/sipxpbx/sipxconfig.properties.in"
    case $Version in
       2.* | 3.*)
           ;;

       '')
           # New installation needs no upgrade.
           ;;

       *)
           echo >&2 "Unknown old version: $Version"
           exit 1
           ;;
    esac
}

##-------------------------------------------------------------------------
## Support functions
##-------------------------------------------------------------------------

MergeRpmConfigFile() { # (config file)
    OriginalFile="${1}"
    RpmFile="${OriginalFile}.rpmnew"
    if test -f ${OriginalFile} && test -f ${RpmFile}; then
        echo `ConfigDiff ${RpmFile} ${OriginalFile}` >> ${OriginalFile}
        rm ${RpmFile}
    fi
}


# Report the line in first file that are not in second file
# in a simple configuration file
#  Example Format
#    # comment here
#    value=property
#
ConfigDiff() { # (File with new props, Original file)
    NewFile=${1}
    OriginalFile=${2}
    KeyValueDelim="="

    NewKeys=`ConfigKeys $NewFile $KeyValueDelim`
    OriginalKeys=`ConfigKeys $OriginalFile $KeyValueDelim`

    for Key in $NewKeys
    do
        Match=`echo $OriginalKeys | grep $Key`
        if [ -z "$Match" ]
        then
            NewLine=`grep ^${Key}${KeyValueDelim} $NewFile`
            echo $NewLine
        fi 
     done
}

# Extracts just the keys, does not support wrapped lines
# assumes comments start with '#' char
ConfigKeys() { # (file, delim)
    grep -v "^\#" $1 | sed -e "s,${2}.*\$,,"
}

SipxCheck() {
    rm -f /tmp/sipxversion.tmp
    CheckInst=`rpm -qa | grep ${1}-[0-9]`

    InstVersion=`expr match "$CheckInst" '.*-\([0-9]*.[0-9]*.[0-9]*-[0-9]*\)'`
    if [ -n "${InstVersion}" ]; then
        echo ${InstVersion} > /tmp/sipxversion.tmp
    fi
}

# $1 - if present, is the old version number to use, rather than reading
# the old version number from /tmp/sipxversion.tmp.
SipxReadVersion() {
    Version=""
    if [ -n "$1" ]; then
        Version=$OldVersion
        # Make sure the user specified a sensible version number, which 
        # is either a triple-dotted-number, or null.
        if ! echo "$Version" | grep -sE '^([0-9]+\.[0-9]+\.[0-9]+)?$'; then
            echo >&2 "Bad format for --oldversion: $1"
            exit 1
        fi
    elif [ -f /tmp/sipxversion.tmp ]; then
        Version=`cat /tmp/sipxversion.tmp`
    else
      # On a fresh install we have not version file, so just exit,
      # don't give an error
      exit 0
    fi

    SplitVersion "$Version"
    Version="${Major}.${Minor}.${Sub}"
    ShortVersion="${Major}.${Minor}"
}

SplitVersion() {
    Major=0
    Minor=0
    Sub=0
    Rel=0
    if [ -n "$1" ]; then
        Major=`expr match "$1" '\([0-9]*\).'`
        Minor=`expr match "$1" '[0-9]*.\([0-9]*\)'`
        Sub=`expr match "$1" '[0-9]*.[0-9]*.\([0-9]*\).'`
        Rel=`expr match "$1" '[0-9]*.[0-9]*.[0-9]*-\([0-9]*\)'`
    fi
}

# Add a config item to a configuration file, if it does not already
# exist in the file.
# $1 - the file
# $2 - the config item
# $3 - the value to add
AddConfigLine() {
    # Check if there is already a line in the file.
    if ! grep -q "^ *$2 *:" $1
    then
        # If not, append the new line.
        echo "$2: $3" >>$1
    fi
}

## Handle command line arguments
while [ "$#" -ne 0 ]
do
    case ${1} in
        -c | --check)
            Action="Check"
            ;;

        -u | --upgrade)
            Action="Upgrade"
            ;;

        -n | --nooperation)
            Action="NoOperation"
            ;;

        -p | --project)
            shift
            Project=${1}
            ;;    

        --bdir)
            shift
            BinDir=${1}
            ;;

        --ddir)
            shift
            DataDir=${1}
            ;;

        --cdir)
            shift
            SysConfDir=${1}
            ;;

        --sdir)
            shift
            LocalStateDir=${1}
            ;;

        --oldversion)
            # Specify a version number for the installed system, rather
            # than reading /tmp/sipxversion.tmp.
            shift
            OldVersion=${1}
            ;;

        *)
            echo >&2 "Incomprehensible argument or switch: $1"
            exit 1
            ;;
    esac
    shift
done

# Check that a project was specified.
if [ -z "$Project" ]; then
    echo >&2 "No project specified.  Use -p."
    exit 1
fi

# Perform the requested operation.
case "$Action" in

    Check)
        SipxCheck "$Project"
        ;;

    Upgrade)
        SipxReadVersion $OldVersion
        if [ -n "$Version" ]; then
          SipxUpgrade
        else
          echo >&2 "Unable to determine version of installed system."
          echo >&2 "Did you run '$0 --check'?"
          echo >&2 "Or use --oldversion."
          exit 1
        fi
        ;;

    NoOperation)
        ;;

    *)
        echo >&2 "No action specified: Specify -c or -u."
        ;;

esac
