#!/bin/bash
# -----------------------------------------------------------------------------
# Downloads and sets-up Apache Karaf as a basis for running ONOS locally
# as a single-instance.
#
# Note that this in no way impacts the method for running ONOS remotely.
# For that, one should use onos-package and onos-install tools.
# -----------------------------------------------------------------------------

[ ! -d "$ONOS_ROOT" ] && echo "ONOS_ROOT is not defined" >&2 && exit 1
. $ONOS_ROOT/tools/build/envDefaults

# TODO: consider putting this under ~/Applications/onos/apache-karaf-...
export KARAF_ROOT=${KARAF_ROOT:-~/Applications/apache-karaf-$KARAF_VERSION}
export STAGE=$(dirname $KARAF_ROOT)

# Validates the specified IP regular expression against existing adapters.
# Excludes local-loopback.
function validateIp {
    ifconfig | awk '{ print $2}' | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep $1
}

# Parse optional arguments
while [[ $# > 0 ]]; do
    case $1 in
    clean)
        CLEAN="true";;
    secure)
        SECURE="true";;
    *)
        break;;
    esac
    shift
done

ONOS_IP=${ONOS_IP:-127.0.0.1}
IP="${1:-$ONOS_IP}"

# If the installed version does not line-up with ONOS_POM_VERSION force clean install
if [ ! -f $KARAF_ROOT/etc/org.apache.karaf.features.cfg ] || \
    ! grep -q "mvn:org.onosproject/onos-features/$ONOS_POM_VERSION/xml/features" \
        $KARAF_ROOT/etc/org.apache.karaf.features.cfg; then
    echo "Existing ONOS Karaf uses version different from $ONOS_POM_VERSION; forcing clean install..."
    CLEAN="true"
fi

# If clean option was specified, wipe-out existing installation
if [ "$CLEAN" = "true" ]; then
    echo "Removing existing ONOS Karaf, apps, and config directories..."
    [ -d $KARAF_ROOT ] && rm -fr $KARAF_ROOT $STAGE/apps $STAGE/config
fi

# If IP was not given, nor configured attempt to use ONOS_NIC env. variable
if [ -z "$IP" -a -n "$ONOS_NIC" ]; then
    IP=$(validateIp $ONOS_NIC)
    [ -z "$IP" ] && echo "No adapter with IP matching $ONOS_NIC found!"
else
    # Otherwise, verify that the IP address given exists among the adapters.
    saveIp=$IP
    IP=$(validateIp $IP)
    [ -z "$IP" ] && echo "No adapter with IP $saveIp found!"
fi

# If IP is still not surmised or if usage was requested, show usage and IPs.
if [ -z "$IP" -o "$1" = "-?" -o "$1" = "-h" -o "$1" = "--help" ]; then
    echo "usage: $(basename $0) [clean] [secure] <ip-address>"
    echo "Available IP addresses are:"
    validateIp .
    exit 1
fi

SUBNET="$(echo $IP | cut -d. -f1-3)"

# Bail on any errors
set -e

# Check if Apache Karaf is already installed.
if [ ! -d $KARAF_ROOT ]; then
    # Check if Apache Karaf bits are available and if not, fetch them.
    if [ ! -f $KARAF_TAR ]; then
        echo "Downloading $KARAF_TAR..."
        curl -sL http://downloads.onosproject.org/third-party/apache-karaf-$KARAF_VERSION.tar.gz --create-dirs -o $KARAF_TAR
    fi
    [ ! -f $KARAF_ZIP -a ! -f $KARAF_TAR ] && \
        echo "Apache Karaf bits $KARAF_ZIP or $KARAF_TAR not found" && exit 1

    echo "Unpacking $KARAF_TAR to $STAGE..."
    mkdir -p $STAGE
    cd $STAGE
    tar zxf $KARAF_TAR
    rm -rf $KARAF_ROOT/demos
fi

if [ "$SECURE" = "true" ]; then
    echo "Enabling security mode ONOS..."

    # SM-ONOS step 1: downgrade felix config admin
    FELIX_CFG_ADMIN=${FELIX_CFG_ADMIN:-~/Downloads/org.apache.felix.configadmin-1.6.0.jar}
    if [ ! -f $FELIX_CFG_ADMIN ]; then
        echo "Downloading $FELIX_CFG_ADMIN..."
        curl -sL http://archive.apache.org/dist/felix/org.apache.felix.configadmin-1.6.0.jar > $FELIX_CFG_ADMIN
    fi
    [ ! -f $FELIX_CFG_ADMIN ] && \
        echo "Felix config admin not found: $FELIX_CFG_ADMIN" && exit 1

    mkdir -p $KARAF_ROOT/system/org/apache/felix/org.apache.felix.configadmin/1.6.0
    cp $FELIX_CFG_ADMIN $KARAF_ROOT/system/org/apache/felix/org.apache.felix.configadmin/1.6.0
    perl -pi.old -e "s|^(.*org.apache.felix.configadmin.*)|mvn\\\\:org.apache.felix/org.apache.felix.configadmin/1.6.0 = 10|" \
        $KARAF_ROOT/etc/startup.properties

    # SM-ONOS step 2: stage ONOS Felix framework security (will get downloaded on demand); end

    # SM-ONOS step 3.1: configure karaf
    perl -pi.old -e "s|#java.security.policy|java.security.policy|" \
        $KARAF_ROOT/etc/system.properties
    perl -pi.old -e "s|#org.osgi.framework.security|org.osgi.framework.security|" \
        $KARAF_ROOT/etc/system.properties
fi

if ! grep -q "/onos-features/" $KARAF_ROOT/etc/org.apache.karaf.features.cfg; then
    # Patch the Apache Karaf distribution file to add ONOS features repository
    echo "Adding ONOS feature repository..."
    perl -pi.old -e "s|^(featuresRepositories=.*)|\1,mvn:org.onosproject/onos-features/$ONOS_POM_VERSION/xml/features|" \
        $KARAF_ROOT/etc/org.apache.karaf.features.cfg
fi

if ! grep -q ",onos-api," $KARAF_ROOT/etc/org.apache.karaf.features.cfg; then
    # Patch the Apache Karaf distribution file to load default ONOS boot features
    export BOOT_FEATURES="webconsole,onos-api,onos-core,onos-incubator,onos-cli,onos-rest,onos-gui"
    if [ "$SECURE" = "true" ]; then
        # SM-ONOS Step 3.2: add onos-security to featuresBoot
        export BOOT_FEATURES="onos-security,$BOOT_FEATURES"
    fi
    echo "Adding ONOS boot features $BOOT_FEATURES..."
    perl -pi.old -e "s|^(featuresBoot=.*)|\1,$BOOT_FEATURES|" \
        $KARAF_ROOT/etc/org.apache.karaf.features.cfg
fi

if [ ! -f $KARAF_ROOT/lib/onos-branding-$ONOS_POM_VERSION.jar ]; then
    # Patch the Apache Karaf distribution with ONOS branding bundle
    echo "Branding as ONOS..."
    rm -f $KARAF_ROOT/lib/onos-branding-*.jar
    cp $M2_REPO/org/onosproject/onos-branding/$ONOS_POM_VERSION/onos-branding-$ONOS_POM_VERSION.jar \
        $KARAF_ROOT/lib
fi

echo "Creating local cluster configs for IP $IP..."
[ -d $STAGE/config ] || mkdir -p $STAGE/config
cat > $STAGE/config/cluster.json <<EOF
{
  "name": "default",
  "nodes": [ {"id": "$IP", "ip": "$IP", "port": 9876 } ],
  "partitions": [ { "id": 0, "members": [ "$IP" ] }, { "id": 1, "members": [ "$IP" ] } ]
}
EOF

if [ "$CLEAN" = "true" ]; then
    echo "Copying package configs..."
    cp -r $ONOS_ROOT/tools/package/etc/* $KARAF_ROOT/etc/
    cp -r $ONOS_ROOT/tools/package/config/* $STAGE/config/
fi

echo "Staging builtin apps..."
rm -fr $STAGE/apps
onos-stage-apps $STAGE/apps $KARAF_ROOT/system

ACTIVE_APPS=${ONOS_APPS:-drivers,openflow}
echo "Customizing apps to be auto-activated: $ACTIVE_APPS..."
for app in ${ACTIVE_APPS//,/ }; do
    touch $STAGE/apps/org.onosproject.$app/active
done
