#!/usr/bin/env bash

# Copyright 2017 Jose Nelson Amaral
# Copyright 2017 Joao Hoffman
# Copyright 2017 Morgan Redshaw
# Copyright 2017 Erick Ochoa Lopez
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

__name__="${BASH_SOURCE[0]}"
pushd `dirname "${__name__}"` > /dev/null ; __dir__=$(pwd -P) ; popd >/dev/null
__help__=<< EOM

EOM


echo "Removing invalid and duplicated includes..."

if [ ! -d modified ]; then
   mkdir modified
fi

if [ ! -d pre ]; then
   mkdir pre
fi

# All the .h and .c.inc files will be copied to a 'modified' dir.
find src -name "*.h" -exec cp {} modified \;
find src -name "*.c.inc" -exec cp {} modified \;
# All the .c files will be copied to the 'modified' dir, but they will have their names changed according to the directory structure. For instance, a 'example.c' file inside the src/dir folder will be moved to the modified directory with the name src_dir_example.c.
find src -type f -name '*.c' -exec bash -c 'ext="${0##*.}"; base="$(basename "$0" ."${ext}")"; dirs="$(dirname "$0" | tr / _)"; new="modified/${dirs}_${base}.${ext}"; cp "$0" "${new}"' {} \;

# Calls the script to remove duplicated includes and test the file.
python $__dir__/processIncludes
gcc -E modified/includes.c -o modified/test_includes.c

# If it can't be preprocessed, the script is paused for manual inspection.
if [ ! -e modified/test_includes.c ]; then
   read -n 1 -s -p "Manual inspection required: the 'modified/includes.c' file could not be preprocessed successfully. Please, try to fix the errors before continuing with the script."
   echo ""
   exit
else
   rm modified/test_includes.c
fi

# Make this a .txt file to prevent it to be appended in a random place.
mv modified/includes.c modified/includes.txt

echo "Preprocessing the files..."

# All the .c files will be preprocessed here.
for i in modified/*.c; do
   filename=$(basename "$i")
   gcc $i -E -o pre/$filename
done

rm temp.txt

echo "Removing code from includes in each preprocessed file..."
rm modified/*.c

# The included code in each preprocessed file must be removed to prevent duplications.
for i in pre/*.c; do
   filename=$(basename "$i")
   bash $__dir__/removeLineMarkers $i modified/$filename
done

# These lines will guide the ANTLR code towards the correct file scopes later on.
for i in modified/*.c; do
      filename=$(basename "$i")
      echo "#BEGIN ${filename%%.*}" | cat - $i > temp && mv temp $i
      echo "#CLOSE ${filename%%.*}" >> $i
done

if [ ! -d final ]; then
   mkdir final
fi

echo "Mangling the names and generating final file..."

# Set the environment up and calls the ANTLR code.
export CLASSPATH="$__dir__:/usr/local/lib/antlr-4.5.3-complete.jar:$CLASSPATH"
for i in modified/*.c; do
      java -jar $__dir__/nameMangler.jar $i >> final/$1 2> /dev/null
      if [ $? -ne 0 ] ; then
        echo "jar did not execute correctly, do you have the correct java
version?"
        exit
      fi
done

# Pre-processes and prepends the 'includes.c', and remove the extra lines that were added in before.
mv modified/includes.txt modified/includes.c
gcc -E modified/includes.c -o includes.c
cat includes.c | cat - final/$1 > temp && mv temp final.c
sed '/#BEGIN/d' ./final.c > final2.c
sed '/#CLOSE/d' ./final2.c > final3.c
sed '/<EOF>/d' ./final3.c > $1

echo "Removing temporary files and directories..."

rm -r modified pre final final.c final2.c final3.c includes.c

echo "Done!"
