#!/bin/bash

CURDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

function assert_ret_zero {
    if [ "$1" -ne 0 ]; then
        if [ ! -z "$2" ]; then
            echo "$2"
        fi
        exit 1
    fi
}

function check_submodules {
    [ -n "`git submodule status | grep -E '^\-'`" ] && kodev-fetch-thirdparty
}

function setup_env {
    files=$(ls -d ./koreader-emulator-*/koreader)
    assert_ret_zero $? "Emulator not found, please build it first."
    export EMU_DIR=${files[0]}
}

function kodev-fetch-thirdparty {
    make fetchthirdparty
}

SUPPORTED_TARGETS="
    kindle          For kindle with touch support
    kindle5         For kindle models >= kindle5 < paper white 2
    kindlepw2       For kindle models >= paper white 2
    kindle-legacy   For kindle2/3/4/DXG
    kobo
    android
    pocketbook
    ubuntu-touch
    emu             (*default) If no TARGET is given, assume emulator
    win32
"

function kodev-build {
    BUILD_HELP_MSG="
usage: build <OPTIONS> <TARGET>

OPTIONS:

    -v, --verbose   Build in verbose mode.

TARGET:
${SUPPORTED_TARGETS}"

    while [[ $1 == '-'* ]]; do
        PARAM=$(echo "$1" | awk -F= '{print $1}')
        VALUE=$(echo "$1" | awk -F= '{print $2}')
        case $PARAM in
            -v | --verbose)
                export VERBOSE=1 ;;
            -h | --help)
                echo "${BUILD_HELP_MSG}"; exit 0 ;;
            *)
                echo "ERROR: unknown option \"$PARAM\""
                echo "${BUILD_HELP_MSG}"
                exit 1 ;;
        esac
        shift 1
    done

    check_submodules
    case $1 in
        kindle)
            make TARGET=kindle; assert_ret_zero $? ;;
        kindle5)
            make TARGET=kindle5; assert_ret_zero $? ;;
        kindlepw2)
            make TARGET=kindlepw2; assert_ret_zero $? ;;
        kobo)
            make TARGET=kobo; assert_ret_zero $? ;;
        kindle-legacy)
            make TARGET=kindle-legacy; assert_ret_zero $? ;;
        android)
            [[ -n ${NDK+x} ]] || export NDK="${CURDIR}/base/toolchain/android-ndk-r12b"
            [ -e ${CURDIR}/base/toolchain/android-toolchain/bin/arm-linux-androideabi-gcc ] || { \
                { [ -e ${NDK} ] || make -C ${CURDIR}/base/toolchain android-ndk; }; \
                make android-toolchain; assert_ret_zero $?; \
            }
            echo "Using NDK: ${NDK}..."
            make TARGET=android; assert_ret_zero $? ;;
        pocketbook)
            if [ ! -d "${CURDIR}/base/toolchain/pocketbook-toolchain" ]; then
                make pocketbook-toolchain; assert_ret_zero $?
            fi
            make TARGET=pocketbook; assert_ret_zero $? ;;
        ubuntu-touch)
            make TARGET=ubuntu-touch; assert_ret_zero $? ;;
        win32)
            make TARGET=win32; assert_ret_zero $? ;;
        *)
            make
            assert_ret_zero $? "Failed to build emulator! Try run with -v for more information."
            setup_env ;;
    esac
}

function kodev-clean {
    CLEAN_HELP_MSG="
usage: clean <TARGET>

TARGET:
${SUPPORTED_TARGETS}"

    case $1 in
        -h | --help)
            echo "${CLEAN_HELP_MSG}"; exit 0 ;;
        kindle)
            make TARGET=kindle clean ;;
        kindle5)
            make TARGET=kindle5 clean ;;
        kindlepw2)
            make TARGET=kindlepw2 clean ;;
        kobo)
            make TARGET=kobo clean ;;
        kindle-legacy)
            make TARGET=kindle-legacy clean ;;
        android)
            make TARGET=android clean
            rm -f ./*.apk ;;
        pocketbook)
            make TARGET=pocketbook clean ;;
        ubuntu-touch)
            make TARGET=ubuntu-touch clean ;;
        win32)
            make TARGET=win32 clean ;;
        *)
            make clean ;;
    esac
}

function kodev-release {
    # SUPPORTED_RELEASE_TARGETS=$(echo ${SUPPORTED_TARGETS} | sed 's/win32//')
    SUPPORTED_RELEASE_TARGETS="${SUPPORTED_TARGETS/emu*/""}"
    RELEASE_HELP_MSG="
usage: release <TARGET>

TARGET:
${SUPPORTED_RELEASE_TARGETS}"
    [ $# -lt 1 ] && { echo "${RELEASE_HELP_MSG}"; exit 1; }

    while [[ $1 == '-'* ]]; do
        PARAM=$(echo "$1" | awk -F= '{print $1}')
        VALUE=$(echo "$1" | awk -F= '{print $2}')
        case $PARAM in
            -v | --verbose)
                export VERBOSE=1 ;;
            -h | --help)
                echo "${RELEASE_HELP_MSG}"; exit 0 ;;
            *)
                echo "ERROR: unknown option \"$PARAM\""
                echo "${RELEASE_HELP_MSG}"; exit 1 ;;
        esac
        shift 1
    done

    which tx>/dev/null && make po || echo "WARN: Transifex client not found, no translation pulled."

    case $1 in
        kindle)
            kodev-build kindle
            make TARGET=kindle update ;;
        kindle5)
            kodev-build kindle5
            make TARGET=kindle5 update ;;
        kindlepw2)
            kodev-build kindlepw2
            make TARGET=kindlepw2 update ;;
        kobo)
            kodev-build kobo
            make TARGET=kobo update ;;
        kindle-legacy)
            kodev-build kindle-legacy
            make TARGET=kindle-legacy update ;;
        android)
            kodev-build android
            export PATH=$PATH:${CURDIR}/base/toolchain/android-sdk-linux/tools
            which android &> /dev/null || { \
                make -C ${CURDIR}/base/toolchain android-sdk; \
            }
            export ANDROID_HOME=`dirname $(dirname $(which android))`
            export PATH=$PATH:${NDK}
            make TARGET=android update ;;
        pocketbook)
            kodev-build pocketbook
            make TARGET=pocketbook update ;;
        ubuntu-touch)
            kodev-build pocketbook
            make TARGET=ubuntu-touch update ;;
        *)
            echo "Unsupported target for release: $1."
            echo "${RELEASE_HELP_MSG}"; exit 1 ;;
    esac
}


function kodev-wbuilder {
    kodev-build
    echo "[*] Running wbuilder.lua..."
    pushd "${EMU_DIR}"
        EMULATE_READER_W=540 EMULATE_READER_H=720 ./luajit ./tools/wbuilder.lua
    popd
}

function kodev-run {
    RUN_HELP_MSG="
usage: run <OPTIONS> <ARGS>

OPTIONS:

    -h=X, --screen-height=X set height of the emulator screen (default: 720)
    -w=X, --screen-width=X  set width of the emulator screen (default: 540)
    --no-build              run reader without rebuilding
    --disable-touch         use this if you want to simulate keyboard only devices
    "
    screen_width=540
    screen_height=720
    while [[ $1 == '-'* ]]; do
        PARAM=$(echo "$1" | awk -F= '{print $1}')
        VALUE=$(echo "$1" | awk -F= '{print $2}')
        case $PARAM in
            --disable-touch)
                export DISABLE_TOUCH=1 ;;
            --no-build)
                no_build=true ;;
            -w | --screen-width)
                screen_width=${VALUE} ;;
            -h | --screen-height)
                screen_height=${VALUE} ;;
            -h | --help)
                echo "${RUN_HELP_MSG}"; exit 0 ;;
            *)
                echo "ERROR: unknown option \"$PARAM\""
                echo "${RUN_HELP_MSG}"; exit 1 ;;
        esac
        shift
    done

    if [ ! ${no_build} ]; then
        echo "[*] Building KOReader..."
        kodev-build
    else
        setup_env
    fi

    if [ ! -d "${EMU_DIR}" ]; then
        echo "Failed to find emulator directory! Please try build command first."
        exit 1
    fi

    echo "[*] Running KOReader with arguments: $*..."
    pushd "${EMU_DIR}"
        if [ $# -lt 1 ]; then
            args=${CURDIR}/test
        else
            args="$*"
            [[ $args != /* ]] && args="${CURDIR}/${args}"
        fi

        EMULATE_READER_W=${screen_width} EMULATE_READER_H=${screen_height} \
            ./reader.lua -d "$args"
    popd
}

function kodev-test {
    TEST_HELP_MSG="
usage: test <OPTIONS> [front|base] <TEST_NAME>

    TEST_NAME is optional. If no TEST_NAME is given, all tests will be run.

OPTIONS:

    --tags=TAGS     only run tests with given tags
    "
    while [[ $1 == '-'* ]]; do
        PARAM=$(echo "$1" | awk -F= '{print $1}')
        VALUE=$(echo "$1" | awk -F= '{print $2}')
        case $PARAM in
            --tags)
                opts="--tags=${VALUE}" ;;
            -h | --help)
                echo "${TEST_HELP_MSG}"; exit 0 ;;
            *)
                echo "ERROR: unknown option \"$PARAM\""
                echo "${TEST_HELP_MSG}"; exit 1 ;;
        esac
        shift
    done

    [ $# -lt 1 ] && { echo "${TEST_HELP_MSG}"; exit 1; }
    [[ $1 != "front" && $1 != "base" ]] && {
        echo "Invalid test suite: $1!"
        echo "${TEST_HELP_MSG}"
        exit 1
    }

    check_submodules && make
    setup_env
    make "${EMU_DIR}/.busted"
    pushd "${EMU_DIR}"
        test_path="./spec/$1/unit"

        if [ ! -z "$2" ]; then
            test_path="${test_path}/$2"
        fi

        echo "Runing tests in" ${test_path}
        busted --lua="./luajit" ${opts} \
            --no-auto-insulate \
            --lazy \
            -o "./spec/$1/unit/verbose_print" \
            --exclude-tags=notest "${test_path}"
    popd
}

function kodev-log {
    LOG_HELP_MSG="
usage: log <TARGET>

TARGET:

    android
"
    [ $# -lt 1 ] && { echo "${LOG_HELP_MSG}"; exit 1; }

    case $1 in
        -h | --help)
            echo "${LOG_HELP_MSG}"; exit 0 ;;
        android)
            adb logcat 'luajit-launcher:D KOReader:D *:S' ;;
        *)
            echo "Unsupported target: $1."
            echo "${LOG_HELP_MSG}"; exit 1 ;;
    esac
}



HELP_MSG="
usage: $0 COMMAND <ARGS>

Supported commands:

    activate            Bootstrap shell environment for kodev
    build               Build KOReader
    clean               Clean KOReader build
    fetch-thirdparty    Fetch thirdparty dependencies for build
    log                 Tail log stream for a running KOReader app
    release             Build KOReader release package
    run                 Run KOReader
    test                Run tests
    wbuilder            Run wbuilder.lua script (useful for building new UI widget)
"
[ $# -lt 1 ] && { echo "Missing command."; echo "${HELP_MSG}"; exit 1; }

case $1 in
    activate)
        echo "adding ${CURDIR} to \$PATH..."
        export PATH="${PATH}:${CURDIR}"
        eval "$(luarocks path bin)"
        exec "${SHELL}" ;;
    fetch-thirdparty)
        kodev-fetch-thirdparty ;;
    clean)
        shift 1; kodev-clean "$@" ;;
    build)
        shift 1; kodev-build "$@" ;;
    release)
        shift 1; kodev-release "$@" ;;
    wbuilder)
        kodev-wbuilder ;;
    run)
        shift 1; kodev-run "$@" ;;
    test)
        shift 1; kodev-test "$@" ;;
    prompt)
        kodev-build
        pushd "${EMU_DIR}"
            ./luajit -i setupkoenv.lua
        popd
        ;;
    log)
        shift 1; kodev-log "$@" ;;
    --help | -h)
        echo "${HELP_MSG}"; exit 0 ;;
    *)
        echo "Unknown command: $1."
        echo "${HELP_MSG}"; exit 1 ;;
esac
