#!/bin/echo ERROR: This script needs to be sourced. Please run as .

# toaster - shell script to start Toaster

# Copyright (C) 2013-2015 Intel Corp.

# This program is free software; 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 in the hope that it will be useful,
# but 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.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.

HELP="
Usage: source toaster start|stop [webport=<address:port>] [noweb]
    Optional arguments:
        [noweb] Setup the environment for building with toaster but don't start the development server
        [webport] Set the development server (default: localhost:8000)
"

webserverKillAll()
{
    local pidfile
    for pidfile in ${BUILDDIR}/.toastermain.pid ${BUILDDIR}/.runbuilds.pid; do
        if [ -f ${pidfile} ]; then
            pid=`cat ${pidfile}`
            while kill -0 $pid 2>/dev/null; do
                kill -SIGTERM -$pid 2>/dev/null
                sleep 1
            done
            rm  ${pidfile}
        fi
    done
}

webserverStartAll()
{
    # do not start if toastermain points to a valid process
    if ! cat "${BUILDDIR}/.toastermain.pid" 2>/dev/null | xargs -I{} kill -0 {} ; then
        retval=1
        rm "${BUILDDIR}/.toastermain.pid"
    fi

    retval=0
    # you can always add a superuser later via
    # ../bitbake/lib/toaster/manage.py createsuperuser --username=<ME>
    $MANAGE migrate --noinput || retval=1

    if [ $retval -eq 1 ]; then
        echo "Failed migrations, aborting system start" 1>&2
        return $retval
    fi
    # Make sure that checksettings can pick up any value for TEMPLATECONF
    export TEMPLATECONF
    $MANAGE checksettings --traceback || retval=1

    if [ $retval -eq 1 ]; then
        printf "\nError while checking settings; aborting\n"
        return $retval
    fi

    echo "Starting webserver..."

    $MANAGE runserver "$ADDR_PORT" \
           </dev/null >>${BUILDDIR}/toaster_web.log 2>&1 \
           & echo $! >${BUILDDIR}/.toastermain.pid

    sleep 1

    if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then
        retval=1
        rm "${BUILDDIR}/.toastermain.pid"
    else
        echo "Toaster development webserver started at http://$ADDR_PORT"
        echo -e "\nYou can now run 'bitbake <target>' on the command line and monitor your build in Toaster.\nYou can also use a Toaster project to configure and run a build.\n"
    fi

    return $retval
}

INSTOPSYSTEM=0

# define the stop command
stop_system()
{
    # prevent reentry
    if [ $INSTOPSYSTEM -eq 1 ]; then return; fi
    INSTOPSYSTEM=1
    webserverKillAll
    # unset exported variables
    unset TOASTER_DIR
    unset BITBAKE_UI
    unset BBBASEDIR
    trap - SIGHUP
    #trap - SIGCHLD
    INSTOPSYSTEM=0
}

verify_prereq() {
    # Verify Django version
    reqfile=$(python3 -c "import os; print(os.path.realpath('$BBBASEDIR/toaster-requirements.txt'))")
    exp='s/Django\([><=]\+\)\([^,]\+\),\([><=]\+\)\(.\+\)/'
    exp=$exp'import sys,django;version=django.get_version().split(".");'
    exp=$exp'sys.exit(not (version \1 "\2".split(".") and version \3 "\4".split(".")))/p'
    if ! sed -n "$exp" $reqfile | python3 - ; then
        req=`grep ^Django $reqfile`
        echo "This program needs $req"
        echo "Please install with pip install -r $reqfile"
        return 2
    fi

    return 0
}

# read command line parameters
if [ -n "$BASH_SOURCE" ] ; then
    TOASTER=${BASH_SOURCE}
elif [ -n "$ZSH_NAME" ] ; then
    TOASTER=${(%):-%x}
else
    TOASTER=$0
fi

export BBBASEDIR=`dirname $TOASTER`/..
MANAGE="python3 $BBBASEDIR/lib/toaster/manage.py"
OE_ROOT=`dirname $TOASTER`/../..

# this is the configuraton file we are using for toaster
# we are using the same logic that oe-setup-builddir uses
# (based on TEMPLATECONF and .templateconf) to determine
# which toasterconf.json to use.
# note: There are a number of relative path assumptions
# in the local layers that currently make using an arbitrary
# toasterconf.json difficult.

. $OE_ROOT/.templateconf
if [ -n "$TEMPLATECONF" ]; then
    if [ ! -d "$TEMPLATECONF" ]; then
        # Allow TEMPLATECONF=meta-xyz/conf as a shortcut
        if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then
            TEMPLATECONF="$OE_ROOT/$TEMPLATECONF"
        fi
    fi
fi

unset OE_ROOT

# this defines the dir toaster will use for
# 1) clones of layers (in _toaster_clones )
# 2) the build dir (in build)
# 3) the sqlite db if that is being used.
# 4) pid's we need to clean up on exit/shutdown
# note: for future. in order to make this an arbitrary directory, we need to
# make sure that the toaster.sqlite file doesn't default to `pwd` like it currently does.
export TOASTER_DIR=`pwd`

WEBSERVER=1
ADDR_PORT="localhost:8000"
unset CMD
for param in $*; do
    case $param in
    noweb )
            WEBSERVER=0
    ;;
    start )
            CMD=$param
    ;;
    stop )
            CMD=$param
    ;;
    webport=*)
            ADDR_PORT="${param#*=}"
            # Split the addr:port string
            ADDR=`echo $ADDR_PORT | cut -f 1 -d ':'`
            PORT=`echo $ADDR_PORT | cut -f 2 -d ':'`
            # If only a port has been speified then set address to localhost.
            if [ $ADDR = $PORT ] ; then
                ADDR_PORT="localhost:$PORT"
            fi
    ;;
    --help)
            echo "$HELP"
            return 0
    ;;
    *)
            echo "$HELP"
            return 1
    ;;

    esac
done

if [ `basename \"$0\"` = `basename \"${TOASTER}\"` ]; then
    echo "Error: This script needs to be sourced. Please run as . $TOASTER"
    return 1
fi

verify_prereq || return 1

# We make sure we're running in the current shell and in a good environment
if [ -z "$BUILDDIR" ] ||  ! which bitbake >/dev/null 2>&1 ; then
    echo "Error: Build environment is not setup or bitbake is not in path." 1>&2
    return 2
fi

# this defines the dir toaster will use for
# 1) clones of layers (in _toaster_clones )
# 2) the build dir (in build)
# 3) the sqlite db if that is being used.
# 4) pid's we need to clean up on exit/shutdown
# note: for future. in order to make this an arbitrary directory, we need to
# make sure that the toaster.sqlite file doesn't default to `pwd`
# like it currently does.
export TOASTER_DIR=`dirname $BUILDDIR`

# Determine the action. If specified by arguments, fine, if not, toggle it
if [ "$CMD" = "start" ] ; then
    if [ -n "$BBSERVER" ]; then
	echo " Toaster is already running. Exiting..."
	return 1
fi
elif [ "$CMD" = "" ]; then
    echo "No command specified"
    echo "$HELP"
    return 1
fi

echo "The system will $CMD."

# Execute the commands

case $CMD in
    start )
        # check if addr:port is not in use
        if [ "$CMD" == 'start' ]; then
            if [ $WEBSERVER -gt 0 ]; then
                $MANAGE checksocket "$ADDR_PORT" || return 1
            fi
        fi

        # Create configuration file
        conf=${BUILDDIR}/conf/local.conf
        line='INHERIT+="toaster buildhistory"'
        grep -q "$line" $conf || echo $line >> $conf

        if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then
            echo "Failed ${CMD}."
            return 4
        fi
        export BITBAKE_UI='toasterui'
        $MANAGE runbuilds & echo $! >${BUILDDIR}/.runbuilds.pid
        # set fail safe stop system on terminal exit
        trap stop_system SIGHUP
        echo "Successful ${CMD}."
        return 0
    ;;
    stop )
        stop_system
        echo "Successful ${CMD}."
    ;;
esac
