#!/bin/bash -x
## SPDX-License-Identifier: GPL-3.0-or-later

##   Copyright ©  2021 - 2022 CEA (Commissariat à l'énergie atomique et aux énergies alternatives)
##   contributed by Basile Starynkevitch (working at CEA, LIST, France)
##   <basile@starynkevitch.net> or <basile.starynkevitch@cea.fr>
##
##   This program is free software: you can redistribute it and/or modify
##   it under the terms of the GNU General Public License as published by
##   the Free Software Foundation, either version 3 of the License, or
##   (at your option) any later version.
##
##   This program is distributed in the hope that it will be useful,
##   but WITHOUT ANY WARRANTY; without even the implied warranty of
##   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##   GNU General Public License for more details.
##
##   You should have received a copy of the GNU General Public License
##   along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##   ----
##   Contact me (Basile Starynkevitch) by email
##   basile@starynkevitch.net and/or basile.starynkevitch@cea.fr
##   -----------

### script file Hello-World-Analyze in github.com/bstarynk/bismon


## the analyzed "hello-world" program has two C source files in
## TestHelloWorld/testhw-sayhello.c and TestHelloWorld/testhw-main.c

### the generated header file _bm_config.h should exist, since it has been created by running successfully the ./Configure script
if [ ! -f _bm_config.h ]; then
    printf "%s: missing _bm_config.h in directory %s\n" $0 $(pwd) > /dev/stderr
    printf "... Please run the ./Configure script in this directory %s\n" $(pwd) > /dev/stderr
    exit 1
fi

declare hello_analysis_need_bismon_build
if [ ! -x bismon ]; then
    hello_analysis_need_bismon_build=yes
else
    for bmsrc in [a-z]*BM.c ; do
	if [ $bmsrc -nt bismon ] ; then
	    hello_analysis_need_bismon_build=yes
	fi
    done
fi

if [ -n "$hello_analysis_need_bismon_build" ]; then
    declare -i build_bismon_code
    [ -f bismon ] && /bin/mv -vf bismon bismon~
    ### our Build script is using shell variables like BISMON_MAKE
    ### (e.g. the GNU make) BISMON_MAKE_FLAGS
    printf "%s: needs to build bismon  in directory %s\n" $0 $(pwd) > /dev/stderr
    ./Build
    build_bismon_code=$?
    if [ $build_bismon_code -gt 0 ]; then
	printf "%s: failed to build bismon using ./Build (exited %d) in directory %s\n" $0 \
	       $build_bismon_code $(pwd) > /dev/stderr
	exit $build_bismon_code
    else
	printf "%s: succeeded in building bismon using ./Build  in directory %s\n" $0  > /dev/stderr
	/bin/ls -l ./bismon > /dev/stderr
    fi
fi

declare -a bismon_hello_args

for f in "$@"; do
    case "$f" in
	--bismon*) bismon_hello_args+=$f;;
	--asm) export BISMON_PLUGIN_ASMOUT=/tmp/gcc11_metaplugin_BMGCC.s;;
	--gcc=*) export BISMON_GCC=$(echo $f | /bin/sed -e s/--gcc=//);;
    esac
done


echo "$0:" bismon arguments $bismon_hello_args in $(pwd) > /dev/stderr

#if [ -z "$BISMON_WEB_BASE" ]; then
#    export BISMON_WEB_BASE=localhost:8086
#fi

if [ -z "$BISMON_GCC" ]; then
    export BISMON_GCC=/usr/bin/gcc-12
fi

if [ -z "$BISMON_PIDFILE" ]; then
    export BISMON_PIDFILE=_bismon.pid
fi

rm /tmp/bismon.cookie
rm -rf /tmp/bismonsigusr1hw.dir*

# https://serverfault.com/a/477506
# https://stackoverflow.com/q/69251163/841108
if [ ${#bismon_hello_args[@]} -eq 0 ]; then
#    bismon_hello_args+=("--bismon-web-base=$BISMON_WEB_BASE")
    bismon_hello_args+=("--bismon-unix-json-socket=/tmp/bismon.sock")
    bismon_hello_args+=("--bismon-project-name=HelloWorld_Project")
#   bismon_hello_args+=("--bismon-debug-after-load")
    bismon_hello_args+=("--bismon-pid-file=$BISMON_PIDFILE")
#    bismon_hello_args+=("--bismon-anon-web-cookie=/tmp/bismon.cookie")
    bismon_hello_args+=("--bismon-sigusr1-dump-prefix=/tmp/bismonsigusr1hw.dir")
fi

#### check existence of needed GCC plugin files

if [ ! -d gccplugins/ ]; then
    echo "$0:" missing gccplugins/ directory in $(pwd) > /dev/stderr
    exit 1
fi

if [ ! -f gccplugins/gcc12_metaplugin_BMGCC.cc ]; then
    echo  "$0:" missing gccplugins/gcc12_metaplugin_BMGCC.cc in $(pwd) > /dev/stderr
    exit 1
fi

if [ ! -f gccplugins/gcc12_metaplugin_BMGCC.hh ]; then
    echo  "$0:" missing gccplugins/gcc12_metaplugin_BMGCC.hh in $(pwd) > /dev/stderr
    exit 1
fi

if [ ! -x gccplugins/build-gcc12-metaplugin.sh ]; then
    echo  "$0:" missing or bad gccplugins/build-gcc12-metaplugin.sh script in $(pwd) > /dev/stderr
    exit 1
fi



################################################################
########## start Bismon

if [ ! -x bismon ]; then
    echo "$0:" cannot start missing Bismon > /dev/stderr
    exit 1
fi

printf "\n\n\n ==== %s: starting Bismon ======\n\n" "$0"
echo '#° ./bismon' $bismon_hello_args

export BISMON_PID=$$

trap "echo $0 terminating Bismon $BISMON_PID; kill -TERM $BISMON_PID" TERM
trap "echo $0 quitting Bismon $BISMON_PID; kill -QUIT $BISMON_PID" QUIT
trap "echo $0 interrupting Bismon $BISMON_PID; kill -INT $BISMON_PID" INT

### perhaps we should use the coproc Bash keyword?
### See https://www.gnu.org/software/bash/manual/html_node/Coprocesses.html
## 
##Bad: ./bismon $bismon_hello_args &
##Bad ./bismon  $bismon_hello_args[*] &
## https://stackoverflow.com/q/69251163/841108
./bismon "${bismon_hello_args[@]}" &
export BISMON_PID=$!
sleep 0.8

printf "\n%s: Bismon pid is %s\n" $0 $BISMON_PID

sleep 1.2
if [ ! -d /proc/$BISMON_PID ]; then
    printf "%s: Bismon pid %d died ****\n" $0 $BISMON_PID >& /dev/stderr
    exit 1
fi

### on some Debian, there is a bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=980609
pushd gccplugins
if [ -f gcc12_metaplugin_BMGCC.so ]; then
    ## force recompilation of plugin if older than plugin source code
    if [ gcc12_metaplugin_BMGCC.so -ot gcc12_metaplugin_BMGCC.cc ]; then
	/bin/rm gcc12_metaplugin_BMGCC.so
    elif [ gcc12_metaplugin_BMGCC.so -ot gcc12_metaplugin_BMGCC.hh ]; then
	/bin/rm gcc12_metaplugin_BMGCC.so
    fi
fi
### Notice: the build-gcc12-metaplugin.sh script cares about a BISMON_PLUGIN_ASMOUT shell variable...
./build-gcc12-metaplugin.sh
popd

printf "\n%s: Bismon compiling TestHelloWorld/testhw-main.c (pid %d)\n" $0 $$
$BISMON_GCC -O -Wall -g -c -v \
		-fplugin=gccplugins/gcc12_metaplugin_BMGCC.so \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-url=localhost:8086 \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-project=HelloWorld_Project \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-pid=$BISMON_PID \
		TestHelloWorld/testhw-main.c -o /tmp/testhw-main.o || exit 1

printf "\%s: Bismon compiling TestHelloWorld/testhw-sayhello.c (pid %d)\n" $0 $$
$BISMON_GCC -O -Wall -g -c -v \
		-fplugin=gccplugins/gcc12_metaplugin_BMGCC.so \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-url=localhost:8086 \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-project=HelloWorld_Project \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-pid=$BISMON_PID \
		TestHelloWorld/testhw-sayhello.c -o /tmp/testhw-sayhello.o || exit 1


printf "\%s: Bismon linking TestHelloWorld (pid %d)\n" $0 $$
$BISMON_GCC -O -Wall -g -v \
		-fplugin=gccplugins/gcc12_metaplugin_BMGCC.so \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-url=localhost:8086 \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-project=HelloWorld_Project \
		-fplugin-arg-gcc12_metaplugin_BMGCC-bismon-pid=$BISMON_PID \
		  /tmp/testhw-main.o /tmp/testhw-sayhello.o -o /tmp/testhelloworld


### something should be using Frama-C, see https://frama-c.com/
