#!/bin/bash

### GLOBAL VARIABLES #########################################################
INFORMATION_COLOR="$(printf "\\033[0;32m")"
DEFAULT_COLOR="$(printf "\\033[0;39m")"
IMPORTANT_COLOR="$(printf "\\033[1;31m")"
WARNING_COLOR="$(printf "\\033[4;33m")"

LKT_DEBUG=""                # Whether or not to build in debug mode
LKT_STATIC_MODULES=""       # Build modules inside liblektor.so or not
LKT_COMPILER=""             # The compiler to use, the basename
LKT_STEP=""                 # Steps: configure, build, etc
LKT_DIR="$PWD"              # The project directory
LKT_CONFIGURE_OPTIONS=""    # Options to pass to the configure command
LKT_CORE_NUMBER=4           # Number of cores to use with make
LKT_TEST=""                 # Which tests to perform
LKT_SRC=$SRC_DIR            # Where to find the sources of lektor
LKT_WORK=$WORK_DIR          # The work dir, where to play

# Below: global variables that will be initialized latter
LKT_INSTALL=""              # Install folder of lektor
LKT_BUILD=""                # Build folder of lektor

### AVAILABLE TESTS ##########################################################

function test_simple ()
{
    check_cd $LKT_INSTALL
    ./lektord &
    local _child_pid=$!
    ./lkt pwd=hashire adm kil
    sleep 5
    kill $_child_pid
}

### Utility functions ########################################################
function die ()
{
    printf "$IMPORTANT_COLOR$@$DEFAULT_COLOR\n"
    exit 1
}

function check_cd ()
{
    [ $# -ne 1 ] && die "Invalid number of argument '$#' for cd command"
    cd $1        || die "Can't go to folder $1"
}

function check_mkdir ()
{
    mkdir $* || die "Failed to mkdir '$*'"
}

function check_configure ()
{
    $LKT_DIR/configure $* || die "Failed to configure with $LKT_COMPILER"
}

function check_make ()
{
    make $* || die "Failed to make with compiler $LKT_COMPILER"
}

function help ()
{
cat << EOF
Usage validate.bash --build=* --step=* [option]

    --help, -h      Prints this help message.
    --build=comp    Specify the compiler.
    --step=AA,BB,.. Specify the steps to do. The list may contains the
                    following items: configure, launch, build.

Step configure options:
    --debug             Perform a debug build.
    --static-modules    Build modules inside liblektor.so, not in their own
                        .so files.

Step launch options:
    --test=AA,BB,..     Perform the specified tests.

EOF
}

if ! [ -f $PWD/scripts/validate.bash ] ; then
    die "This script should be run from the root of the project, you are in $PWD"
fi
SQLITE3=$(which sqlite3)
[ $? -ne 0 ] && die "Can't find the sqlite3 executable"

### PREPARE ##################################################################
# Globals:                                                                   #
# - LKT_COMPILER            Which compiler to use                            #
# - LKT_WORK                The base folder which will contains all the      #
#                           builds and installs                              #
function do_prepare ()
{
    check_mkdir -p $LKT_WORK/{build.$LKT_COMPILER,install.$LKT_COMPILER}
    echo "Created folders $LKT_WORK/{build.$LKT_COMPILER,install.$LKT_COMPILER}"
}

### CONFIGURE ################################################################
# Globals:                                                                   #
# - LKT_DIR                 Project root directory                           #
# - LKT_COMPILER            The compiler used to build                       #
# - LKT_CONFIGURE_OPTIONS   Options to pass to the configure command         #
function do_configure ()
{
    check_cd $LKT_BUILD
    check_configure                                                          \
        --prefix=$LKT_DIR/install.$LKT_COMPILER                              \
        $LKT_CONFIGURE_OPTIONS
    check_cd $LKT_DIR
}

### BUILD THE PROJECT ########################################################
# Globals:                                                                   #
# - LKT_DIR                 Project root directory                           #
# - LKT_COMPILER            The compiler used to build                       #
function do_build ()
{
    check_cd $LKT_BUILD
    check_make -j$LKT_CORE_NUMBER
    check_make install
    check_cd $LKT_DIR
}

### PERFORM THE STEPS ########################################################
# Globals:                                                                   #
# - LKT_STEP                Steps to perform                                 #
function do_steps ()
{
    local _prepare=""
    local _build=""
    local _configure=""
    local _launch=""
    for step in $LKT_STEP ; do
        case "$step" in
            build)      _build="yes";;
            configure)  _configure="yes";;
            launch)     _launch="yes";;
            prepare)    _prepare="yes";;
        esac
    done

    [ "x$_prepare"   = "xyes" ] && do_prepare
    [ "x$_configure" = "xyes" ] && do_configure
    [ "x$_build"     = "xyes" ] && do_build
    [ "x$_launch"    = "xyes" ] && do_launch
}

### PERFORM THE TESTS ########################################################
# Globals:                                                                   #
# - LKT_TEST                Which tests to perform                           #
# - LKT_DIR                 The project root directory                       #
function do_launch ()
{
    for test in $LKT_TEST ; do
        case "$test" in
            simple)     test_simple;;
            *)          die "Test not available"
        esac
    done
}

### PROCESS ARGS #############################################################
# Globals:                                                                   #
# - LKT_DEBUG               Whether or not to build in debug mode            #
# - LKT_STATIC_MODULES      Build lektor modules inside liblektor.so         #
# - LKT_CONFIGURE_OPTIONS   Options to pass to the configure command         #
function process_args ()
{
    if [ "x$LKT_DEBUG" = "xyes" ] ; then
        LKT_CONFIGURE_OPTIONS="$LKT_CONFIGURE_OPTIONS --with-debug"
    fi
    if [ "x$LKT_STATIC_MODULES" = "xyes" ] ; then
        LKT_CONFIGURE_OPTIONS="$LKT_CONFIGURE_OPTIONS --with-static-module"
    fi
    LKT_CONFIGURE_OPTIONS="$LKT_CONFIGURE_OPTIONS CC=$LKT_COMPILER"
}

### PARSE ARGS ###############################################################
for arg in $* ; do
    case "$arg" in
        --help|-h)
            help
            exit 0
            ;;
        --debug)
            LKT_DEBUG="yes"
            ;;
        --build=*)
            LKT_COMPILER=$(echo "A$arg" | sed -e 's/A--build=//g')
            ;;
        --static-modules)
            LKT_STATIC_MODULES="yes"
            ;;
        --step=*)
            LKT_STEP=$(echo "A$arg" | sed -e 's/A--step=//g' -e 's/,/ /g')
            ;;
        --test=*)
            LKT_TEST=$(echo "A$arg" | sed -e 's/A--test=//g' -e 's/,/ /g')
            ;;
        *)
            die "Unknown argument $arg"
            ;;
    esac
done

### GLOBALS THAT NEEDS ARGUMENTS TO BE INITIALIZED ###########################
# - LKT_INSTALL             Where lektor will be installed                   #
# - LKT_BUILD               Where lektor will be configured                  #
LKT_INSTALL=$WORK_DIR/install.$LKT_COMPILER
LKT_BUILD=$WORK_DIR/build.$LKT_COMPILER

### DO OUR STUFF HERE ########################################################
process_args
do_steps
exit 0