#!/bin/sh

CLAN=/home/daniel/polyhedral_perforation/clan-0.8.0/clan
PERF=./build/perf2
CLOOG=/home/daniel/polyhedral_perforation/pluto/cloog-isl/cloog
PLUTO=/home/daniel/polyhedral_perforation/pluto/polycc

usage() {
    printf -- "%s: <OPTIONS> <INPUT>\n" "$0"
    printf -- "perforate program\n\n"
    printf -- "-o, --output FILE   output file\n"
    printf -- "-a, --all           do all steps\n"
    printf -- "-e, --extract       extract scop\n"
    printf -- "-p, --perforate     perforate scop\n"
    printf -- "-g, --generate      generate perforated program\n"
    printf -- "-s, --statement     statement to perforate\n"
    printf -- "-l, --level         level to perforate\n"
    printf -- "-P, --pluto         run pluto\n"
    printf -- "--parallelize       pluto parallelize\n"
}

extract_scop() {
    $CLAN "$1" > "$2"
}

perforate() {
    $PERF "$1" "$2" "$3" "$4"
}

run_pluto() {
    if [ "$1" = "yes" ]; then
        args="--parallelize"
        shift
    else
        args=""
    fi

    # FIXME: what pluto options should be used?
    $PLUTO "$args" -o "$2" "$1" > /dev/null
}

generate() {
    $CLOOG -openscop "$1" > "$2"
}

# default values
output_src=""
statement=0
level=0

while true; do
    case "$1" in
        -h|--help)
            usage
            exit
            ;;
        -a|--all)
            cmd_extract=yes
            cmd_perforate=yes
            cmd_generate=yes
            cmd_pluto=yes
            ;;
        -e|--extract)
            cmd_extract=yes
            ;;
        -p|--perforate)
            cmd_perforate=yes
            ;;
        -g|--generate)
            cmd_generate=yes
            ;;
        -o|--output)
            shift
            output_src="$1"
            ;;
        -s|--statement)
            shift
            statement="$1"
            ;;
        -l|--level)
            shift
            level="$1"
            ;;
        -P|--pluto)
            cmd_pluto=yes
            ;;
        --parallelize)
            cmd_pluto_parallelize=yes
            ;;
        *)
            break
    esac
    shift
done

input_src="$1"

scop="$input_src.openscop"
perforated="$input_src.perf.openscop"
pluto_input="${input_src}_pluto_input.c"


if [ "$input_src" = "" ]; then
    printf "missing input\n"
    exit 1
fi

if [ "$cmd_extract" = "yes" ]; then
    extract_scop "$input_src" "$scop"
fi

if [ "$cmd_perforate" = "yes" ]; then
    perfin="$(mktemp)"
    perfout="$(mktemp)"
    cat "$scop" > "$perfin"
    IFS="_"
    echo statement is $statement
    for s in $statement; do
        IFS=" "
        echo perforate "$perfin" "$perfout" "$s" "$level"
        perforate "$perfin" "$perfout" "$s" "$level"
        tmp="$perfin"
        perfin="$perfout"
        perfout="$tmp"
    done
    cat "$perfin" > "$perforated"
    rm "$perfin" "$perfout"
else
    # no perforation, just copy to perforated
    cat "$scop" > "$perforated"
fi

if [ "$cmd_generate" = "yes" ] || [ "$cmd_pluto" = "yes" ]; then
    generate "$perforated" "$pluto_input"
fi

if [ "$cmd_pluto" = "yes" ]; then
    printf "running pluto on %s output %s\n" "$pluto_input" "$output_src"
    if [ "$cmd_pluto_parallelize" = "yes" ]; then
        run_pluto --parallelize "$pluto_input" "$output_src"
    else
        run_pluto "$pluto_input" "$output_src"
    fi
elif [ "$cmd_generate" = "yes" ]; then
    # no pluto, just copy to output_src
    cat "$pluto_input" > "$output_src"
fi

printf "input is \"%s\" output is \"%s\"\n" "$input_src" "$output_src"
