#!/bin/sh

# The location where the persistent data store is located
PERSISTENT_DATA_DIR=/var/lib/spinetix/persistent-data

PERSISTENT_LICENSES_FILE="$PERSISTENT_DATA_DIR"/licenses
CURRENT_LICENSES_FILE=/etc/spinetix/licenses

# The file with the decoded and validated license data
LICENSE_FEATURES_FILE=/run/licensecheck/license-features.json

# If not empty skip reloading the daemons
SKIP_RELOAD=

# If not empty skip doing updates of configuration
SKIP_UPDATE=

# If not empty then the current licenses file is authoritative
CURRENT_LICENSES_IS_AUTHORITATIVE=1

# Checks that all the license features given as arguments are present and valid
check_license_features()
{
    local f
    for f in "$@"; do
        jq --exit-status --arg feature "$f" \
            '.features | map(select(.name == $feature and .valid == true) | .valid) | any' > /dev/null \
            < "$LICENSE_FEATURES_FILE" \
            || return
    done

    return 0
}

get_license_type()
{
    # There may be multiple license types, we need to select the most
    # capable one, the order being SYSTEMS, KIOSK, WIDGETS, and other types
    # are sorted after, alphabetically.
    jq -r '.features |
        map(select(.valid == true and (.name | startswith("_")))) |
        map(.name |
            sub("^(?<m>_SYSTEMS)"; "A\(.m)") |
            sub("^(?<m>_KIOSK)"; "B\(.m)") |
            sub("^(?<m>_WIDGETS)"; "C\(.m)") |
            sub("^_"; "Z_")
        ) |
        sort | first // "" |
        sub("^._"; "")' < "$LICENSE_FEATURES_FILE"
}

sync_persistent_copy()
{
    if [ ! -f "$CURRENT_LICENSES_FILE" ]; then
        if [ -n "$CURRENT_LICENSES_IS_AUTHORITATIVE" ]; then
            # licenses have been removed, make sure we remove the persistent copy, if any
            if [ -f "$PERSISTENT_LICENSES_FILE" ]; then
                echo "removing license from persistent copy"
                rm -f "$PERSISTENT_LICENSES_FILE" || return
                fsync "$PERSISTENT_DATA_DIR" 2>/dev/null || sync || return
            fi
        else
            # no current licenses file, attempt to recover persistent copy if any
            if [ -f "$PERSISTENT_LICENSES_FILE" ]; then
                echo "recovering license from persistent copy"
                cp "$PERSISTENT_LICENSES_FILE" "$CURRENT_LICENSES_FILE".tmp || return
                fsync "$CURRENT_LICENSES_FILE".tmp 2>/dev/null || sync || return
                mv "$CURRENT_LICENSES_FILE".tmp "$CURRENT_LICENSES_FILE" || return
            fi
        fi
    elif [ -f "$PERSISTENT_LICENSES_FILE" ] && cmp -s "$CURRENT_LICENSES_FILE" "$PERSISTENT_LICENSES_FILE"; then
        # persistent copy is present and identical current licenses file, nothing to do
        return
    else
        # update persistent copy to match current licenses file
        echo "updating persistent copy with new license file"
        cp "$CURRENT_LICENSES_FILE" "$PERSISTENT_LICENSES_FILE".tmp || return
        fsync "$PERSISTENT_LICENSES_FILE".tmp 2>/dev/null || sync || return
        mv "$PERSISTENT_LICENSES_FILE".tmp "$PERSISTENT_LICENSES_FILE" || return
        fsync "$PERSISTENT_DATA_DIR" 2>/dev/null || sync || return
    fi
}

update_httpd()
{
    conf="/run/licensecheck/httpd-defs.conf"
    link=/etc/apache2/conf.d/01-licensecheck-defs.conf
    tmpl="$link".tmpl

    # generate a temporary config file according to license features
    tmpconf="$(mktemp "$conf".XXXXXX)" || return
    type="$(get_license_type)"
    ftype="$type"
    [ -n "$ftype" ] || ftype="none"
    sstype="/^\s*Define\s\s*LicenseType\s/s!\(LicenseType\).*!\1 $ftype!"
    if [ -n "$type" ]; then
        sed -e 's/^\s*#\s*\(Define\s\+ContentServer\)/\1/' -e "$sstype" "$tmpl" > "$tmpconf"
    else
        sed -e 's/^\s*#\s*\(Define\s\+OnlyUploaderPublish\)/\1/' -e "$sstype" "$tmpl" > "$tmpconf"
    fi
    if [ $? -ne 0 ]; then
        rm "$tmpconf"
        return 1
    fi

    # if no change then cleanup and exit
    if [ -f "$conf" ] && cmp -s "$tmpconf" "$conf"; then
        rm "$tmpconf"
        return 0
    fi

    # update the configuration
    if ! mv "$tmpconf" "$conf"; then
        rm "$tmpconf"
        return 1
    fi
    if [ ! -h "$link" ]; then
        if ! ln -sf "$conf" "$link"; then
            rm -f "$link"
            return 1
        fi
    fi

    # reload http server if running
    if [ -z "$SKIP_RELOAD" -a -f /run/httpd.pid ]; then
        echo "licensecheck changed httpd configuration, reloading"
        httpd -k graceful
    fi
}

update_discovery()
{
    conf="/run/licensecheck/discovery.conf"
    disable_publish=true
    disable_im=true

    tmpconf="$(mktemp "$conf".XXXXXX)" || return
    type="$(get_license_type)"
    if [ -n "$type" ]; then
        disable_publish=
    fi
    if check_license_features MULTI; then
        disable_im=
    fi

    echo "DISCOVERY_NO_PUBLISH=$disable_publish" >> "$tmpconf"
    echo "DISCOVERY_NO_IM=$disable_im" >> "$tmpconf"

    # if no change then cleanup and exit
    if [ -f "$conf" ] && cmp -s "$tmpconf" "$conf"; then
        rm "$tmpconf"
        return 0
    fi

    # update the configuration
    if ! mv "$tmpconf" "$conf"; then
        rm "$tmpconf"
        return 1
    fi

    # update the services
    if [ -z "$SKIP_RELOAD" -a -f /run/avahi-daemon/pid -a -x /etc/init.d/spxmanage-mdns ]; then
        echo "licensecheck updated discovery configuration, reloading mDNS"
        /etc/init.d/spxmanage-mdns reload
    fi
    if [ -z "$SKIP_RELOAD" -a -f /run/spxupnp/spxupnpd.pid -a -x /etc/init.d/spxmanage-spxupnpd ]; then
        echo "licensecheck updated discovery configuration, reloading UPnP"
        /etc/init.d/spxmanage-spxupnpd reload
    fi
}

RET=0

if [ "$1" = "--init" ]; then
    # we may need to recover the license from persistent storage
    CURRENT_LICENSES_IS_AUTHORITATIVE=
    SKIP_RELOAD=1
    SKIP_UPDATE=1
fi

sync_persistent_copy || RET=1
if [ -z "$SKIP_UPDATE" ]; then
    update_httpd || RET=1
    update_discovery || RET=1
fi

exit $RET
