#!/bin/bash

SYS_VERSION_FILE="/etc/version"
VERSION_FILE="/data/etc/version"
POST_UPGRADE_DIR="/usr/share/post-upgrade"
POST_UPGRADE_NET_SCHEDULED="/data/.post-upgrade-net-scheduled"
POST_UPGRADE_APP_SCHEDULED="/data/.post-upgrade-app-scheduled"

LOG="/var/log/post-upgrade.log"


test -n "${OS_VERSION}" || source /etc/init.d/base

hash=$(md5sum ${VERSION_FILE} 2>/dev/null | cut -d ' ' -f 1)
sys_hash=$(md5sum ${SYS_VERSION_FILE} 2>/dev/null | cut -d ' ' -f 1)

test "${hash}" == "${sys_hash}" && exit 0

test -d ${POST_UPGRADE_DIR} || exit 0

function version_gt() {
    # Tells if version in $1 > version in $2.

    v1=$1
    v2=$2

    # Trim trailing version components so that both versions are of same length.
    IFS=. v1=(${v1}); unset IFS
    IFS=. v2=(${v2}); unset IFS
    while [[ ${#v1[@]} -gt ${#v2[@]} ]]; do
        unset v1[-1]
    done
    while [[ ${#v2[@]} -gt ${#v1[@]} ]]; do
        unset v2[-1]
    done
    v1=$(echo ${v1[@]} | tr ' ' '.')
    v2=$(echo ${v2[@]} | tr ' ' '.')

    if [[ "${v1}" != "${v2}" ]] && [[ $(echo -e "${v1}\n${v2}" | semver-sort 2>/dev/null | head -n 1) == "${v2}" ]]; then
        return 0
    else
        return 1
    fi
}

function run_post_upgrade() {
    version="$(source ${VERSION_FILE} 2>/dev/null && echo ${OS_VERSION})"
    sys_version="$(source ${SYS_VERSION_FILE} 2>/dev/null && echo ${OS_VERSION})"

    echo "---- post-upgrade from ${version} to ${sys_version} ----" >> ${LOG}

    echo -n > ${POST_UPGRADE_NET_SCHEDULED}
    echo -n > ${POST_UPGRADE_APP_SCHEDULED}
    
    versions=$(ls -1 ${POST_UPGRADE_DIR} | rev | cut -d '.' -f 2-100 | rev)
    for v in ${versions}; do
        # Skip post-upgrade* scripts as they are treated separately.
        if [[ ${v} == post-upgrade* ]]; then
            continue
        fi

        # Don't run scripts for previous (or current) versions.
        if [[ -n "${version}" ]] && ! version_gt ${v} ${version}; then
            continue
        fi

        if [[ ${v} == *-net ]]; then  # scripts that require network
            echo "${POST_UPGRADE_DIR}/${v}.sh" >> ${POST_UPGRADE_NET_SCHEDULED}
            continue
        fi

        if [[ ${v} == *-app ]]; then  # scripts that will be executed right before apps start
            echo "${POST_UPGRADE_DIR}/${v}.sh" >> ${POST_UPGRADE_APP_SCHEDULED}
            continue
        fi
    
        msg_begin "Running post-upgrade script for version ${v}"
        ${POST_UPGRADE_DIR}/${v}.sh >> ${LOG} 2>&1
        test $? == 0 && msg_done || msg_fail
    done
    
    if [[ -x "${POST_UPGRADE_DIR}/post-upgrade.sh" ]]; then
        msg_begin "Running common post-upgrade script"
        ${POST_UPGRADE_DIR}/post-upgrade.sh >> ${LOG} 2>&1
        test $? == 0 && msg_done || msg_fail
    fi
}

case "$1" in
    start)
        run_post_upgrade
        cp ${SYS_VERSION_FILE} ${VERSION_FILE}
        ;;

    stop)
        true
        ;;

    *)
        echo "Usage: $0 {start}"
        exit 1
esac

exit $?
