#!/bin/bash

set -eu

srcdir=$(dirname "$(readlink -f "$0")")
test -z "$srcdir" && srcdir=.

CLANG_FORMAT=${CLANG_FORMAT:-clang-format}
options=()
files=()
lines=()
inplace=0;xml=0;
filename=tmp.1.c
offsets=
off_opts=()
opts=$(getopt -n clang-format-xs -s bash -a -o in -l Werror,assume-filename:,cursor:,dry-run,dump-config,fallback-style:,ferror-limit:,help,length:,lines:,offset:,output-replacement-xmls,sort-includes,style:,verbose,version -- "$@")
if [ $? -ne 0 ]; then exit 1; fi
eval set -- "$opts"; unset opts
while :; do
    case "$1" in
	--offset)
	    offsets="$offsets${offsets:+ }$2"
	    off_opts+=("$1" "$2")
	    shift 2
	    continue
	    ;;
	--length)
	    offsets="$offsets:$2"
	    off_opts+=("$1" "$2")
	    shift 2
	    continue
	    ;;
	--assume-filename)
	    filename="$2"
	    options+=("$1" "$2")
	    shift 2
	    continue
	    ;;
	--lines)
	    lines+=("$2")
	    options+=("$1" "$2")
	    shift 2
	    continue
	    ;;
	--output-replacements-xml)
	    xml=1
	    shift
	    continue
	    ;;
	-i)
	    inplace=1
	    shift
	    continue
	    ;;
	--)
	    shift
	    break
	    ;;
	*)
	    options+=("$1")
	    shift
	    continue
	    ;;
    esac
done
files=("$@")

export IN_LINES="${lines[*]}"
export OFFSETS="$offsets"

options_o=("${options[@]}")
if [[ $inplace = 1 ]]; then
    options_o=("-i" "${options[@]}")
fi
if [[ $xml = 1 ]]; then
    options_o=("-output-replacements-xml" "${options[@]}")
fi
options_o+=("${off_opts[@]}")

do_xs() {
    perl "$srcdir"/format-xs-1.pl "$1" > "$1".1.c
    $CLANG_FORMAT -i "${options[@]}" -- "$1".1.c
    if [[ $xml = 1 ]]; then
	perl "$srcdir"/format-xs-2.pl "$1".1.c > "$1".1.xs
	perl "$srcdir"/format-xs-xml.pl <(diff -U0 <(od -An -tu1 -w1 -v "$1") <(od -An -tu1 -w1 -v "$1".1.xs))
	rm "$1".1.xs
    elif [[ $inplace = 1 ]]; then
	perl "$srcdir"/format-xs-2.pl "$1".1.c > "$1"
    else
	perl "$srcdir"/format-xs-2.pl "$1".1.c
    fi
    rm "$1".1.c
}

if [[ ${#files[@]} -eq 0 ]]; then
    case "$filename" in
	    *.xs)
		cat > "$filename".1.xs
		do_xs "$filename".1.xs
		rm "$filename".1.xs
		;;
	    *)
		$CLANG_FORMAT "${options_o[@]}"
		;;
    esac
else
    for file in "${files[@]}"; do
	case "$file" in
	    *.xs)
		do_xs "$file"
		;;
	    *)
		$CLANG_FORMAT "${options_o[@]}" -- "$file"
		;;
	esac
    done
fi
