#!/bin/bash

DIR_PATH=$(cd `dirname $0`;pwd)
ROOT_PATH=$(cd ${DIR_PATH}/../../;pwd)
REGRESS_PATH=${ROOT_PATH}/pkg/test/og_regress

function help() {
    echo ""
    echo "$0"
    echo ""
    echo "Usage:    Dev_ograc_regress.sh       {help} [--coverage --user]"
    echo "          --coverage         run test with test coverage report"
    echo "          --user             run test with user, if using docker/container.sh dev start container with different user,
                                       pass this user through --user, default is ogracdba"
    echo "          --core_dir        run test with user, if using docker/container.sh dev start container with different coredir,
                                       pass this core dir path through --core_dir, default is /home/core"
    echo "          --og_schedule_list run test with specified test list, default is full test cases list og_schedule"
}


function collect_core() {
	collect_script=${ROOT_PATH}/CI/script/collect_corefile_ograc.sh
	sh ${collect_script} ${CORE_DIR} ${TEMP_DIR} ${ROOT_PATH} ${TEST_DATA_DIR}/data  ${RUN_TEST_USER}
}

function print_regress_diffs() {
    local diff_dir="${ROOT_PATH}/pkg/test/og_regress/results"
    local diff_file

    if ls "${diff_dir}"/*.diff >/dev/null 2>&1; then
        echo "========================= Regress Diff Begin =======================" | tee -a ${REGRESS_LOG}
        for diff_file in "${diff_dir}"/*.diff; do
            [ -f "${diff_file}" ] || continue
            echo "----- ${diff_file} -----" | tee -a ${REGRESS_LOG}
            cat "${diff_file}" | tee -a ${REGRESS_LOG}
            echo "" | tee -a ${REGRESS_LOG}
        done
        echo "========================== Regress Diff End ========================" | tee -a ${REGRESS_LOG}
        mkdir -p ${TEMP_DIR}/diff
        cp "${diff_dir}"/*.diff ${TEMP_DIR}/diff
    else
        echo "No regress diff files found under ${diff_dir}" | tee -a ${REGRESS_LOG}
    fi
}

function run_og_regress() {
	echo "========================= Run Regression ======================="
	cd ${ROOT_PATH}
	# git clean -nf |grep "pkg/test/og_regress/*.*"|xargs rm -f
	cp -f ${ROOT_PATH}/output/bin/og_regress ${REGRESS_PATH}
	chmod u+x ${REGRESS_PATH}/og_regress
	chown -R ${RUN_TEST_USER}:${RUN_TEST_USER} ${REGRESS_PATH}
    su - ${RUN_TEST_USER} -c "cd ${REGRESS_PATH} && sh ogdb_regress_ograc.sh ${TEST_DATA_DIR}/install ${SYS_PASSWD} ${OG_SCHEDULE_LIST} 2>&1 "| tee ${REGRESS_LOG}
    set +e
    fail_count=`grep -c ":  FAILED" ${REGRESS_LOG}`
	ok_count=`grep -c ":  OK" ${REGRESS_LOG}`
    set -e
	if [ $fail_count -ne 0 ] || [ $ok_count -eq 0 ]; then
		echo "Error: Some cases failed when og_regress!!"
		echo "Error: Some cases failed when og_regress!!" >> ${REGRESS_LOG} 2>&1
        print_regress_diffs
		echo "Regress Failed! Regress Failed! Regress Failed! "
		collect_core # local debug, can annotate this step
		exit 1
	fi
	echo "Regress Success"
    regress_result="Test Result: Success";
    echo ${regress_result} > ${ROOT_PATH}/regress_output/test_result.txt
	echo "LCOV_ENABLE is ${LCOV_ENABLE}"
	if [ "${LCOV_ENABLE}" = TRUE ]; then
		echo "make lcov report"
		gen_lcov_report
	fi
}

function uninstall_ogracdb() {
    echo "========================= Uninstall ogracDB ======================="
    chown -R ${RUN_TEST_USER}:${RUN_TEST_USER} /home/regress/ograc_data
    rm -f ${UDF_CFG}
    su - ${RUN_TEST_USER} -c "python3 ${TEST_DATA_DIR}/install/bin/uninstall.py -U ${RUN_TEST_USER} -F -D ${TEST_DATA_DIR}/data -g withoutroot -d"
}

function install_ogracdb() {
    CREATEDB_SQL=${REGRESS_PATH}/sql/create_cluster_database.gsregress.sql
    DATA_PATH=${TEST_DATA_DIR}/data/data
    ESCAPE_DATA_PATH=${DATA_PATH//'/'/'\/'}
    sed -i 's/dbfiles1/'${ESCAPE_DATA_PATH}'/g' ${CREATEDB_SQL}

    echo "========================= Install ogracDB ======================="
    cd ${ROOT_PATH}/output/bin/oGRAC-DATABASE-LINUX-64bit
    python3 install.py -U ${RUN_TEST_USER}:${RUN_TEST_USER}  \
                       -R ${TEST_DATA_DIR}/install/  \
                       -D ${TEST_DATA_DIR}/data/  \
                       -l ${INSTALL_LOG_DIR}/install.log  \
                       -Z SESSIONS=200  \
                       -Z BUF_POOL_NUM=1  \
                       -Z VARIANT_MEMORY_AREA_SIZE=32M  \
                       -Z AUDIT_LEVEL=3  \
                       -Z USE_NATIVE_DATATYPE=TRUE  \
                       -Z _SYS_PASSWORD=${SYS_PASSWD}  \
                       -Z _LOG_LEVEL=255  \
                       -Z _LOG_MAX_FILE_SIZE=10M  \
                       -Z STATS_LEVEL=TYPICAL  \
                       -Z REACTOR_THREADS=1  \
                       -Z OPTIMIZED_WORKER_THREADS=100  \
                       -Z MAX_WORKER_THREADS=100  \
                       -Z UPPER_CASE_TABLE_NAMES=TRUE  \
                       -Z SHARED_POOL_SIZE=1G  \
                       -Z TEMP_BUFFER_SIZE=256M  \
                       -Z DATA_BUFFER_SIZE=2G  \
                       -Z _MAX_VM_FUNC_STACK_COUNT=10000  \
                       -Z MAX_COLUMN_COUNT=4096  \
                       -Z AUTO_INHERIT_USER=ON  \
                       -Z PAGE_CHECKSUM=TYPICAL  \
                       -Z JOB_QUEUE_PROCESSES=100  \
                       -Z CHECKPOINT_PERIOD=300  \
                       -Z LOG_BUFFER_SIZE=4M  \
                       -Z RECYCLEBIN=TRUE  \
                       -Z ENABLE_IDX_KEY_LEN_CHECK=TRUE  \
                       -Z EMPTY_STRING_AS_NULL=TRUE  \
                       -Z SHARED_POOL_SIZE=2G  \
                       -f ${CREATEDB_SQL}  \
                       -g withoutroot -d -M ogracd -c
    result=`cat ${TEST_DATA_DIR}/data/log/ogracstatus.log |grep 'instance started'|wc -l`
    sed -i 's/'${ESCAPE_DATA_PATH}'/dbfiles1/g' ${CREATEDB_SQL}
    if [ $result -eq 0 ]; then
        echo "Error: install ogracdba failed"
        exit 1
    fi
    su - ${RUN_TEST_USER} -c "OGSQL_SSL_QUIET=TRUE ${TEST_DATA_DIR}/install/bin/ogsql sys/${SYS_PASSWD}@127.0.0.1:1611 -f ${ROOT_PATH}/pkg/test/ora-dialect.sql >> ${INSTALL_LOG_DIR}/install.log 2>&1"
    if [ $? -ne 0 ]; then
        echo "Error: create ora-dialect failed"
        exit 1
    fi
}

function compile_code() {
    echo "==================== Begin Rebuild ogracKernel ================="
    lcov_build_flag=""
    if [ "${LCOV_ENABLE}" = TRUE ]
    then 
        lcov_build_flag="lcov=1"
        cp -f ${ROOT_PATH}/pkg/src/server/srv_main.c ${ROOT_PATH}/pkg/src/server/srv_main.c.bak
        echo "finish modify main function"
    fi

    cd ${ROOT_PATH}/build
    sh Makefile.sh clean
    echo "### Compile & Make ogracKernel and OGSQL, no errors and warnings are allowed"
    sh Makefile.sh make_ograc_pkg_test ${lcov_build_flag} | tee -a ${COMPILE_LOG}
#    error_num=`cat ${COMPILE_LOG} |grep 'error:'|wc -l`
#    ignore_error=`cat ${COMPILE_LOG} |grep 'error: unexpected end of file'|wc -l`
#    if [ $error_num -ne 0 ]; then
#        if [ ${ignore_error} != ${error_num} ]; then
#            echo "Error: make ogracKernel & OGSQL failed with errors"
#            exit 1
#        fi
#    fi
#    error_num=`cat ${COMPILE_LOG} |grep 'warning:'|wc -l`
#    if [ $error_num -ne 0 ]; then
#        echo "Error: make ogracKernel & OGSQL failed with warnings"
#        exit 1
#    fi
    echo "### Compile & Make ogracKernel and OGSQL success"
    echo "### Compile & Make test fold source file, no errors and warnings are allowed"
    cd ${ROOT_PATH}/build
    source ./common.sh
    cd ${ROOT_PATH}/build/pkg/test/og_regress
    strip -N main ${ROOT_PATH}/output/lib/libogserver.a
    make -sj 8 | tee -a ${COMPILE_LOG}
#    error_num=`cat ${COMPILE_LOG} |grep 'error:'|wc -l`
#    if [ $error_num -ne 0 ];then

#        if [ ${ignore_error} != ${error_num} ]; then
#            echo "Error: make test fold source file failed with errors"
#            exit 1
#        fi
#    fi
#    error_num=`cat ${COMPILE_LOG} |grep 'warning:'|wc -l`
#    if [ $error_num -ne 0 ];then
#        echo "Error: make test fold source file failed with warnings"
#        exit 1
#    fi
    if [ "${LCOV_ENABLE}" = TRUE ]
    then 
        # 恢复编译之前被修改的源码文件
        mv -f ${ROOT_PATH}/pkg/src/server/srv_main.c.bak ${ROOT_PATH}/pkg/src/server/srv_main.c
        echo "Restoring the srv_main.c file"
        # 修改编译后gcov生成的*.gcno和*.gcda文件属组,用户RUN_TEST_USER运行用例时生成覆盖率报告
        chown ${RUN_TEST_USER}:${RUN_TEST_USER} -R ${ROOT_PATH}/build
    fi
    echo "### Compile & Make test fold source file success"
}

gen_lcov_report()
{
    pid=`ps aux | grep ogracd |grep -v grep |awk '{print $2}'`
    sleep 5
    kill -35 $pid
    if [[ ! -d "${ROOT_PATH}/lcov_output" ]]
    then 
	    mkdir -p ${ROOT_PATH}/lcov_output
        echo "mkdir ${ROOT_PATH}/lcov_output"
    fi
    coverage_info_name="${ROOT_PATH}/lcov_output/Dev_ct_regress_test_coverage_${OG_SCHEDULE_LIST}.info"
    coverage_report_name="${ROOT_PATH}/lcov_output/Dev_ct_regress_test_coverage_${OG_SCHEDULE_LIST}.report"
    find ${ROOT_PATH}/ -name "*.gcno" | xargs touch
    lcov --capture --directory ${ROOT_PATH}/ --rc lcov_branch_coverage=1 --output-file "${coverage_info_name}" 
    lcov -l --rc lcov_branch_coverage=1 "${coverage_info_name}" > "${coverage_report_name}" 
    # Reset all execution counts to zero
    lcov -d ${ROOT_PATH}/ -z
    echo " Lcov report successfully "
}

function init_test_environment() {
    rm -rf ${TEST_DATA_DIR}
    rm -rf ${INSTALL_LOG_DIR}
    rm -rf ${TEMP_DIR}
    rm -rf ${CORE_DIR}/*
    mkdir -p ${TEST_DATA_DIR}
    mkdir -p ${INSTALL_LOG_DIR}
    mkdir -p ${TEMP_DIR}
    mkdir -p ${CORE_DIR}
    touch ${COMPILE_LOG}
    touch ${REGRESS_LOG}
    chown -R ${RUN_TEST_USER}:${RUN_TEST_USER} ${TEST_DATA_DIR}
    chown -R ${RUN_TEST_USER}:${RUN_TEST_USER} ${CORE_DIR}

    UDF_CFG=${ROOT_PATH}/pkg/cfg/udf.ini
    echo "self_func_tst.abs" > ${UDF_CFG}
    echo "self_func_tst.ABS" >> ${UDF_CFG}
    echo "self_func_tst.extract" >> ${UDF_CFG}
    echo "self_func_tst.EXTRACT" >> ${UDF_CFG}
    echo "self_func_tst.decode" >> ${UDF_CFG}
    echo "self_func_tst.DECODE" >> ${UDF_CFG}
    cat ${UDF_CFG}
}

function check_old_install() {
    old_install=`ps -aux|grep ogracd|grep "${TEST_DATA_DIR}/data"|wc -l`
    old_env_data=`cat /home/${RUN_TEST_USER}/.bashrc |grep "export OGDB_HOME="|wc -l`
    if [ $old_install -ne 0 ] || [ $old_env_data -ne 0 ]; then
        echo "existing install ogracdb, uninstall it first"
        uninstall_ogracdb
    fi
}

function parse_parameter() {
    ARGS=$(getopt -o c:u:d:g: --long coverage:,user:,core_dir:,og_schedule_list: -n "$0" -- "$@")

    if [ $? != 0 ]; then
        echo "Terminating..."
        exit 1
    fi

    eval set -- "${ARGS}"
    declare -g LCOV_ENABLE=FALSE
    declare -g RUN_TEST_USER="ogracdba"
    declare -g CORE_DIR="/home/core"
    declare -g OG_SCHEDULE_LIST="og_schedule"
    while true
    do
        case "$1" in
            -c | --coverage)
                LCOV_ENABLE=TRUE
                shift 2
                ;;
            -u | --user)
                RUN_TEST_USER="$2"
                shift 2
                ;;
            -d | --core_dir)
                CORE_DIR="$2"
                shift 2
                ;;
            -g | --og_schedule_list)
                OG_SCHEDULE_LIST="$2"
                shift 2
                ;;
            --)
                shift
                break
                ;;
            *)
                help
                exit 0
                ;;
        esac
    done
    # using docker/container.sh dev start container will create user and config core pattern
    # pass this user to the script through --user, default is ogracdba
    declare -g TEST_DATA_DIR="/home/regress/og_regress"
    declare -g INSTALL_LOG_DIR=${TEST_DATA_DIR}/logs
    declare -g TEMP_DIR=${TEST_DATA_DIR}/tmp
    declare -g COMPILE_LOG=${TEST_DATA_DIR}/logs/compile_log
    declare -g REGRESS_LOG=${TEST_DATA_DIR}/logs/regress_log
    declare -g SYS_PASSWD=Huawei@123
}

main() {
    parse_parameter "$@"
    check_old_install
    init_test_environment
    echo "pass_build : ${pass_build}"
    if [ "${pass_build,,}" = "need_compile" ]; then
        echo "Start compile, source code root path: ${ROOT_PATH}" > ${COMPILE_LOG}
        echo "ROOT_PATH: ${ROOT_PATH}"
        compile_code # local debug, if only change sql test file can annotate this step
    else
        chown root:root -R /home/regress/ogracKernel/output/bin
        echo "BUILD passed!"
    fi
    install_ogracdb

    run_og_regress
    uninstall_ogracdb
}

main "$@"