#/******************************************************************************
# * FileName: 
# * Description: 
# * Version: 
# * History: 
# *     huangbucheng    2015-09-11    1.0    created
# * 
# *****************************************************************************/
#!/bin/sh

#set -e
set -x

make_dir=
gtest_dir=
timer=20 #定时器 default 20s
tc_name= #testcase name
disp_html=0
clean_all=1

#functions
function print_usage() {
    echo "usage: create testcase "$0" [-c <testcase_name>] [-d <work_dir>]"
    echo "       run testcase "$0" [-P <testcase_pattern>] [-d <work_dir>] [-g <googletest_dir>] [-t <time_out>] [-p]"
    echo "       default work_dir is ./"
}

function cleanup() {
    rm -rf *.gcno *.gcda *.o gtest/*.o gtest/*.gcno gtest/*.gcda
    rm ${mkfile}
}

function gen_testcase() {
    echo "====generate test case===="
    cd ${make_dir}
    if test ! -d gtest; then
        mkdir gtest
    fi
    file_name="gtest/gtest_"${tc_name}".cc"
    touch ${file_name}
    echo "#include \"gtest/gtest.h\"" >> ${file_name}
    echo "#define private public" >> ${file_name}
    echo "#define protected public" >> ${file_name}
    echo "//add header file of tested object here..." >> ${file_name}
    echo "#undef private" >> ${file_name}
    echo "#undef protected" >> ${file_name}
    echo -e "\n\n\n" >> ${file_name}
    tc_body="class TS_"${tc_name}" : public testing::Test {
    protected:
        static void SetUpTestCase() {}
        static void TearDownTestCase() {}
        virtual void SetUp() {}
        virtual void TearDown() {}\n};\n
TEST_F (TS_"${tc_name}", main) {
    //Add test here...    \n}\n"
    echo -e "${tc_body}" >> ${file_name}
    echo ${file_name} "created"
}

#parse args
while getopts "c:d:g:t:pr" arg #选项后面的冒号表示该选项需要参数
do
    case $arg in
        c)
            tc_name=$OPTARG
            ;;
        d)
            make_dir=$OPTARG
            ;;
        g)
            gtest_dir=$OPTARG
            ;;
        t)
            timer=$OPTARG
            ;;
        p)
            disp_html=1
            ;;
        r)
            clean_all=0
            ;;
    esac
done

if [ -z "${make_dir}" ]; then
    make_dir="./"
fi
if test ! -d ${make_dir}; then
    echo "work directory is invalid: "${make_dir}
    exit 1
fi
echo "work directory is "${make_dir}

if [ -z "${gtest_dir}" ]; then
    gtest_dir="../../library/thrid_lib/googletest"
fi
if test ! -d ${gtest_dir}; then
    echo "google test library directory is invalid: "${gtest_dir}
    exit 1
fi
echo "google test library directory is "${gtest_dir}

if [[ -n "${make_dir}" ]] && [[ -n "${tc_name}" ]];
then
    gen_testcase
    exit 0
fi

if [[ -z "${make_dir}" ]] || [[ -z "${gtest_dir}" ]];
then
    print_usage
    exit 1
fi
#if [ $# -lt 3 ]; then
#    echo "usage: "$0" <make_dir> <googletest_dir> <time_out>"
#    exit 1
#fi

mkfile=gtest_temp.mk
target=gtests

#work directory
if test ! -d gtest; then
    echo "found no gtest directory"
    exit 1
fi
cd ${make_dir}


#prepare makefile
cp ./Makefile ./${mkfile}
sed -i '/^CC=/a\
GTEST_DIR='${gtest_dir} ${mkfile}
sed -i 's/^CFLAGS=/CFLAGS=-fprofile-arcs -ftest-coverage -DGOOGLE_TEST /' ${mkfile}
sed -i 's/^INCLUDE=/INCLUDE=-I$(GTEST_DIR)\/googletest\/include -I.\/ /' ${mkfile}
sed -i 's/^LINK_LIBS=/LINK_LIBS=$(GTEST_DIR)\/build\/googletest\/libgtest.a -fprofile-arcs -ftest-coverage -lpthread /' ${mkfile}
sed -i '/^OBJS=/a\
OBJS+=$(GTEST_DIR)/googletest/src/gtest_main.o \
OBJS+=$(patsubst %.cc,%.o,$(wildcard gtest/*.cc)) \
' ${mkfile}
sed -i '/TARGET/s/\(.*=\)\(.*\)/\1'${target}'/' ${mkfile}
sed -i '$a\
.cleanall: \
	rm -f $(TARGET) $(OBJS) \
	rm -rf *.gcno *.gcda gtest/*.gcno gtest/*.gcda gtest/app.info gtest/results ' ${mkfile}

#clean
lcov --directory ./ --zerocounters
if [ $clean_all -eq 1 ]; then
    make -f ${mkfile} .cleanall
fi

#compile
make -f ${mkfile}
if [ $? -ne 0 ];then
    echo "****make failed"
    exit 1
fi

#execute gtest
if test ! -d gtest/logs; then
    mkdir gtest/logs
fi
./${target}

#wait gtests finish
flag=1 #标识进程是否存在
while [ $timer -gt 0 ]
do
    sleep 2
    if test -z "$(ps -ef | grep ${target} | grep -v grep)"
    then 
        flag=0 && break #进程不存在了就退出循环
    else 
        let timer-=1
    fi
done
if [ $flag -eq 1 ]; then
    echo "****gtests time out"
    pid=$(ps -ef | grep ${target} | grep -v "grep\|awk" | awk '/'${target}'/{print $2}')
    if test -n "$pid"
    then 
        kill -9 $pid 
    fi
    cleanup
    exit 1
fi

#coverage
lcov --directory ./ --capture --output-file ./gtest/app.info
if [ $? -ne 0 ];then
    echo "****lcov failed"
    cleanup
    exit 1
fi

#coverage in html format
gcov_log=$(genhtml -o ./gtest/results ./gtest/app.info)
if [ $? -ne 0 ];then
    echo "****genhtml failed"
    cleanup
    exit 1
fi
#line_cov=$(sed -n '/^  lines......: /p' ${gcov_log})
#echo $line_cov

if [ $clean_all -eq 1 ]; then
    cleanup
fi

#html display of coverage result
if [ $disp_html -eq 1 ]; then
    elinks gtest/results/index.html
fi