#!/bin/bash
#
# test-ide.sh - tizen ui test automantion supporting script
#
# Contact :
# Gyeongseok seo <gyeongseok.seo@samsung.com>
#
# Contributors :
# - S-Core Co., Ltd
#

##
# functions
## 'RESULT' is ALL function's return value 
##
function pre_init ()
{
    OS=$1
    if [[ -z ${OS} ]] ; then
        OS="unix"
    fi
    RESULT=
    TEST_START_TIME=`date +%Y%m%d.%H%M%S`      ## test start time
    TEMP_LOG=.temp.log                         ## temp log file

    if [[ -f "${TEMP_LOG}" ]] ; then
        rm -f ${TEMP_LOG}
    fi
}

## print string given args
function notify ()
{
    local nanos=
    if [[ "${OS}" == "win" ]] ; then
        nanos=`date +%s`
    else
        nanos=`date +%N`
    fi

    if [[ $# -eq 0 ]] ; then
        return 1
    else
        printf "$@\n"

        printf "[`date +%Y.%m.%d' '%H:%M:%S`][TEST_SCRIPT] $@ - [Category: test-ide.sh] at `date +%Y-%m-%d' '%H:%M:%S.${nanos:0:3}`\n" >> ${TEMP_LOG}
        return 0
    fi
}


## print . and wait given time
## first arg - wait time
function printAndwait()
{
    if [[ $# -eq 0 ]] ; then
        return 1
    else
        local cnt=0

        while :
        do
            if [[ ${cnt} -ge $1 ]] ; then
                break;
            fi

            let cnt++
            sleep 1
            printf "."
        done

        return 0
    fi
}


## kill success then RESULT is 0 
## kill failed  then RESULT is 1
function kill_emulator ()
{
    RESULT=1
    notify "emulator process kill..."

    local EM_VM_PID=
    local cnt=0
    while :
    do
        EM_VM_PID=`ps aux | grep test | awk '{ print $2 "\t" $11 }' | grep emulator | awk '{ print $1 }'`

        if [[ -n "${EM_VM_PID}" ]] ; then
            notify "emulator pid : '${EM_VM_PID}'"
            kill -9 ${EM_VM_PID}
            printAndwait 10
        elif [[ ! -n "${EM_VM_PID}" && ${cnt} -eq 0 ]] ; then
            notify "emulator process kill success..."
            break;
        elif [[ ! -n "${EM_VM_PID}" && ${cnt} -gt 0 ]] ; then
            notify "\nemulator process kill success..."
            break;
        fi

        let cnt=cnt+10
        if [ ${cnt} -gt 60 ] ; then
            notify "\nemulator process kill failed..."
            return $RESULT
        fi
    done

    RESULT=0
    return $RESULT
}

## kill success then RESULT is 0 
## kill failed  then RESULT is 1
function kill_ide ()
{
    RESULT=1
    notify "tizen ide process kill..."

    local TIZEN_IDE_PID=
    local cnt=0
    while :
    do
        TIZEN_IDE_PID=`ps aux | grep test | awk '{ print $2 "\t" $11 }' | grep eclipse | awk '{ print $1 }'`

        if [[ -n "${TIZEN_IDE_PID}" ]] ; then
            notify "tizen ide pid : '${TIZEN_IDE_PID}'"
            kill -9 ${TIZEN_IDE_PID}
            printAndwait 10
        elif [[ ! -n "${TIZEN_IDE_PID}" && ${cnt} -eq 0 ]] ; then
            notify "tizen ide process kill success..."
            break;
        elif [[ ! -n "${TIZEN_IDE_PID}" && ${cnt} -gt 0 ]] ; then
            notify "\ntizen ide process kill success..."
            break;
        fi

        let cnt=cnt+10
        if [ ${cnt} -gt 60 ] ; then
            notify "\ntizen ide process kill failed..."
            return $RESULT
        fi
    done

    RESULT=0
    return $RESULT
}

## init success then RESULT is 0
## init failed  then RESULT is 1
function init_variable ()
{
    RESULT=1

    #### variable list
    SCRIPT_PATH=       #### test-ide.sh path
    TIZEN_SDK=         #### tizen-sdk path
    TIZEN_SDK_DATA=    #### tizen-sdk-data path
    TEST_ROOT_PATH=    #### test script and resource path
    TEST_RESULT_PATH=  #### test result collect path
    SIKULI_CMD=        #### sikuli cmd
    SDB_CMD=           #### sdb cmd
    EM_CMD=            #### emulator manager cmd

    #### SCRIPT_PATH is test-ide.sh path
    pushd . > /dev/null
    SCRIPT_PATH="${BASH_SOURCE[0]}";
    while([ -h "${SCRIPT_PATH}" ]) do
        cd "`dirname "${SCRIPT_PATH}"`" 
        SCRIPT_PATH="$(readlink "`basename "${SCRIPT_PATH}"`")";
    done
    cd "`dirname "${SCRIPT_PATH}"`" > /dev/null
    SCRIPT_PATH="`pwd`";
    popd  > /dev/null

    if [ -z ${SCRIPT_PATH} ] ; then
        return $RESULT
    fi
    notify "script\tpath : ${SCRIPT_PATH}"


    #### TIZEN_SDK is tizen-sdk path
    if [ `ls ${SCRIPT_PATH}/../../../sdk.info | grep sdk.info | wc -l` -eq 1 ] ; then
        TIZEN_SDK=`cat ${SCRIPT_PATH}/../../../sdk.info | grep TIZEN_SDK_INSTALLED_PATH= | sed -e s/TIZEN_SDK_INSTALLED_PATH=/""/g`
        TIZEN_SDK_DATA=`cat ${SCRIPT_PATH}/../../../sdk.info | grep TIZEN_SDK_DATA_PATH= | sed -e s/TIZEN_SDK_DATA_PATH=/""/g`
    fi

    if [ -z "$TIZEN_SDK" ]; then
        return $RESULT
    fi

    if [[ "${OS}" == "win" ]] ; then
        TIZEN_SDK=/${TIZEN_SDK//':\'//'/'}
        TIZEN_SDK_DATA=/${TIZEN_SDK_DATA//':\'//'/'}
    fi

    notify "tizen\tpath : ${TIZEN_SDK}"


    #### test script and resource path
    TEST_ROOT_PATH="${SCRIPT_PATH}"
    if [ ! -d "${TEST_ROOT_PATH}" ] ; then
        return $RESULT
    fi


    #### test result collect path
    #TEST_RESULT_PATH="${TIZEN_SDK}/test/ide/result"
    TEST_RESULT_PATH="${TIZEN_SDK_DATA}/test/ide"
    if [ ! -d "${TEST_RESULT_PATH}" ] ; then
        mkdir -p ${TEST_RESULT_PATH}
    fi
    notify "result\tpath : ${TEST_RESULT_PATH}"


    #### sikuli cmd
    SIKULI_CMD="/home/test/sikuli/runIDE"
    notify "sikuli\tcmd  : ${SIKULI_CMD}"


    #### sdb cmd
    SDB_CMD="${TIZEN_SDK}/tools/sdb"
    if [ ! -f "${SDB_CMD}" ] ; then
        return $RESULT
    fi
    notify "sdb\tcmd  : ${SDB_CMD}"


    #### emulator manager cmd
    EM_CMD="${TIZEN_SDK}/tools/emulator/bin/emulator-manager"
    if [ ! -f "${EM_CMD}" ] ; then
        return $RESULT
    fi
    notify "emul\tcmd  : ${EM_CMD}"

    ### all init success
    RESULT=0
    return $RESULT
}


## connection success then RESULT is 0
## connection failed  then RESULT is 1
## first arg - connection check vm name
function check_emulator_connection ()
{
    RESULT=1
    notify "emulator vm sdb connection check..."

    if [[ $# -eq 0 ]] ; then
        notify "emulator vm sdb connection check failed..."
        return $RESULT
    fi

    #### sdb devices cmd
    local SDB_DEVICES_CMD="${SDB_CMD} devices"
    #notify "sdb-device cmd : ${SDB_DEVICES_CMD}"

    local cnt=0
    while :
    do
#        local CHECK=`${SDB_DEVICES_CMD} | awk '{ print $3 }' | grep "$1" | wc -l`
        local CHECK=10 # sdb connection bug... so bypass logic
        if [[ `echo ${CHECK}` -gt 0 && ${cnt} -eq 0 ]] ; then
            notify "emulator vm sdb connection success..."
            break;
        elif [[ `echo ${CHECK}` -gt 0 && ${cnt} -gt 0 ]] ; then
            notify "\nemulator vm sdb connection success..."
            break;
        fi

        let cnt++
        printAndwait 1

        if [ ${cnt} -gt 60 ] ; then
            notify "\nemulator vm sdb connection failed..."
            return $RESULT
        fi
    done

    RESULT=0
    return $RESULT
}


## vm exist then RESULT is 0
## vm not exist  then RESULT is 1
## first arg - check vm name
function check_emulator_vm_list ()
{
    RESULT=1
    notify "emulator vm exist check..."

    if [[ $# -eq 0 ]] ; then
        notify "emulator vm exist check failed..."
        return $RESULT
    fi

    local EM_VM_CHECK="${EM_CMD} list-vm"
    echo "emulator vm exist check cmd : ${EM_VM_CHECK}"
    for name in `${EM_VM_CHECK}`
    do
        if [[ "$name" == "$1" ]] ; then
            RESULT=0
            break;
        fi
    done

    if [[ $RESULT -eq 0 ]] ; then
        notify "emulator vm '$1' is alreay exist..."
    else
        notify "emulator vm '$1' is not exist..."
    fi
    return $RESULT
}


## vm delete success then RESULT is 0
## vm delete failed  then RESULT is 1
## first arg - delete target vm name
function delete_emulator_vm ()
{
    RESULT=1
    notify "emulator vm delete..."

    if [[ $# -eq 0 ]] ; then
        RESULT=0
        notify "emulator vm delete success..."
        return $RESULT
    fi

    local EM_VM_DELETE="${EM_CMD} delete -n $1"
    local CHECK=`${EM_VM_DELETE} | grep Success: | wc -l`
    if [[ $CHECK -eq 0 ]] ; then
        notify "emulator vm '$1' delete failed..."
    elif [[ $CHECK -eq 1 ]] ; then
        RESULT=0
        notify "emulator vm '$1' delete success..."
    fi

    return $RESULT
}


## vm create success then RESULT is 0
## vm create failed  then RESULT is 1
## first arg - create vm name
function create_emulator_vm ()
{
    RESULT=1
    notify "emulator vm create..."

    if [[ $# -eq 0 ]] ; then
        notify "emulator vm create failed..."
        return $RESULT
    fi

    local EM_VM_CREATE="${EM_CMD} create -n $1 -p mobile-3.0"
    local CHECK=`${EM_VM_CREATE} | grep "Success:" | wc -l`
    if [[ $CHECK -eq 0 ]] ; then
        notify "emulator vm '$1' create failed..."
    elif [[ $CHECK -eq 1 ]] ; then
        RESULT=0
        notify "emulator vm '$1' create success..."
    fi

    return $RESULT
}


## vm launch success then RESULT is 0
## vm launch failed  then RESULT is 1
## first arg - launch vm name
function launch_emulator_vm ()
{
    RESULT=1
    notify "emulator vm '$1' launch..."

    if [[ $# -eq 0 ]] ; then
        notify "emulator vm launch failed..."
        return $RESULT
    fi

    local EM_VM_RUN="${EM_CMD} launch -n $1"
    #local CHECK=`${EM_VM_RUN} | grep "Success:" | wc -l`

    ${EM_VM_RUN} > .run
    local CHECK=`cat .run | grep "Success:" | wc -l`
    echo "emulator vm launch cmd : ${EM_VM_RUN}"

    if [[ $CHECK -eq 0 ]] ; then
        notify "emulator vm '$1' launch failed..."
    elif [[ $CHECK -eq 1 ]] ; then
        RESULT=0
        notify "emulator vm '$1' launch success..."
    fi

    return $RESULT
}


## wait 20 sec
function wait_booting_emulator_vm ()
{
    notify "emulator vm booting wait..."
    printAndwait 20
    notify "\nemulator vm booting wait success..."
}

## test workspace create success then RESULT is 0
## test workspace create failed  then RESULT is 1
function create_workspace()
{
    RESULT=1
    notify "test workspace create..."

    if [[ -d "${TEST_ROOT_PATH}/workspace" ]] ; then
        rm -rf ${TEST_ROOT_PATH}/workspace
        #rm -rf ${TEST_ROOT_PATH}/workspace/.metadata/ide-*.log
	rm -f ${TIZEN_SDK_DATA}/ide/logs/ide-*.log
    fi

    if [[ ! -f "${TEST_ROOT_PATH}/ide-test-workspace.zip" ]] ; then
        notify "test workspace create failed..."
        notify "${TEST_ROOT_PATH}/ide-test-workspace.zip is not exist"
        return $RESULT
    else
        unzip ${TEST_ROOT_PATH}/ide-test-workspace.zip -d ${TEST_ROOT_PATH} > /dev/null
    fi

    if [[ ! -f "${TEST_ROOT_PATH}/workspace/test.p12" ]] ; then
        notify "test workspace create failed..."
        notify "${TEST_ROOT_PATH}/workspace/test.p12 is not exist"

        return $RESULT
    else
        cp ${TEST_ROOT_PATH}/workspace/test.p12 ${TIZEN_SDK}/.
    fi

    notify "test workspace create success..."
    RESULT=0
    return $RESULT
}


## sikuli script launch success then RESULT is 0
## sikuli script launch failed  then RESULT is 1
function launch_sikuli_script ()
{
    RESULT=1
    notify "sikuli script launch..."

    ${SIKULI_CMD} -r "${TEST_ROOT_PATH}/tizen-ide-ui-test.sikuli" -- "${TIZEN_SDK}/ide" "${TEST_ROOT_PATH}/workspace" "${OS}" >> ${TEMP_LOG}

    if [[ "[info] Exit code: 0" == "`cat ${TEMP_LOG} | tail -n 1`" ]] ; then
        notify "sikuli script launch success..."
    else
        notify "sikuli script launch failed..."
        return $RESULT
    fi

    RESULT=0
    return $RESULT
}


## create result file and copy
## netcat not default command in windows, so we import window's netcat command (nc.exe)
## window's netcat (nc.exe) license GNU, if you want to more information then read the license.txt file
function create_result ()
{
    local LOGNAME=IDE-TEST.`echo ${TEST_START_TIME}`.log

    echo "TEST SCRIPT LOG ======================================================" > ${TEST_RESULT_PATH}/`echo ${LOGNAME}`
    cat ${TEMP_LOG} >> ${TEST_RESULT_PATH}/`echo ${LOGNAME}`

    echo "IDE LOG ==============================================================" >> ${TEST_RESULT_PATH}/`echo ${LOGNAME}`
    #cat ${TEST_ROOT_PATH}/workspace/.metadata/ide-*.log | grep "PERFORM" >> ${TEST_RESULT_PATH}/`echo ${LOGNAME}`
    cat ${TIZEN_SDK_DATA}/ide/logs/ide-*.log | grep "PERFORM" >> ${TEST_RESULT_PATH}/`echo ${LOGNAME}`

    
    java -cp ${TIZEN_SDK}/test/ide/lib/org.tizen.common-test.jar org.tizen.common.LogConverter ${TEST_RESULT_PATH}/${LOGNAME} ide.perf

}

## 1. close emulator
## 2. close Tizen IDE
## 3. cleanup workspace
## cleanup success then RESULT is 0
## cleanup failed  then RESULT is 1
function cleanup ()
{
    kill_emulator
    kill_ide
    rm -rf ${TEST_ROOT_PATH}/workspace
}

function return_check ()
{
if [ $RESULT -eq 1 ] ; then
    echo "failed"
fi
if [ $RESULT -eq 0 ] ; then
    echo "success"
fi
exit 0
}


##
# main function
#
##
# setup
## 1. init variable
## 2. cleanup previouse resources 
## 3. pre-required resource handle (unzip workspace), make new resource
##
# run
## 1. tizen sdk launch
## 2. sikuli ui test script launch
##
# cleanup
## 1. copy test result
## 2. cleanup 
##
function main ()
{
    pre_init $@

    # setup
    notify "TEST START..."
    init_variable                     ## 1. init variable
    cleanup                           ## 2. cleanup
    check_emulator_vm_list "test"     ## 3.1 test vm exist check
    if [[ $RESULT -eq 0 ]] ; then
        delete_emulator_vm "test"     ## 3.2 test vm is exist then delete
    fi

    create_emulator_vm "test"         ## 3.3 new test vm create
    if [[ $RESULT -eq 1 ]] ; then
        create_result
        exit $RESULT
    fi

    launch_emulator_vm "test"         ## 3.4 new test vm run
    if [[ $RESULT -eq 1 ]] ; then
        create_result
        exit $RESULT
    fi

    wait_booting_emulator_vm          ## 3.5 wait emulator booting
    check_emulator_connection "test"  ## 3.6 new test vm and sdb connection check
    create_workspace                  ## 3.7 pre-required resource create

    # run
    ## tizen sdk launch in sikuli script
    launch_sikuli_script              ## 1&2. sikuli ui test script launch

    # cleanup
    notify "TEST END..."
    create_result                     ## 1. result file copy
    # cleanup                           ## 2. cleanup

    return_check
}

main $@ #startup


