#!/bin/sh
#
# cspell - check spelling in the current git branch
#
# Copyright (C) 2017 Masatake YAMATO
# Copyright (C) 2017 Red Hat Inc.
#
# 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 2 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/>.
#
#
# Usage:
#
#    $ bash misc/cspell
#
CTAGS=${1:-$(pwd)/ctags}
CTAGS_OPTLIB=${2:-$(pwd)/misc/spelling.ctags}
CTAGS_DICTSDIR=${3:-$(pwd)/dictfiles}

base=master
OUTDIR=./SPELL_CHECKING.TMP

count=0
input0=
commit=
dictfile=
errors=
total_errors=0

CTAGS_BASE_OPTION="--quiet --options=NONE"
CTAGS_OPTION="${CTAGS_BASE_OPTION} --options=${CTAGS_OPTLIB}"

for dictfile in ${CTAGS_DICTSDIR}/*.list; do
    if [ "$dictfile" = "${CTAGS_DICTSDIR}/*.list" ]; then
	break;
    fi
    CTAGS_OPTION="${CTAGS_OPTION} --param-UCtagsAspell:dictfile=${dictfile}"
done

mkdir -p ${OUTDIR}

for commit in $(git log --format=%H ${base}...); do
    iname=$(printf "%05d-%s" $count $commit)
    oname=${iname}-misspelling.tags
    git show ${commit} \
	| grep -v -e '^-[^-]' \
	| grep -v -e '^diff ' \
	| grep -v -e '^rename from ' \
	| sed -e 's/\(@@.*@@\).*/\1/' \
	      > ${OUTDIR}/${iname}.txt

    CTAGS_LOCAL_OPTIONS=
    for d in $(for d0 in $(${CTAGS} ${CTAGS_BASE_OPTION} \
				    --language-force=diff \
				    --kinds-diff='{modifiedFile}{newFile}{deletedFile}' \
				    -x --_xformat='%{name}' \
				    ${OUTDIR}/${iname}.txt \
			       | grep 'Tmain\|Units' \
			       | sed -n -e 's|^[ab]/\(.*\)$|\1|p'); do
		   echo $(dirname $d0)
	       done | sort -u); do

	dictfile="$d/dictfile"
	if [ -d "$d" -a -f "$dictfile" ]; then
	    CTAGS_LOCAL_OPTIONS="${CTAGS_LOCAL_OPTIONS} --param-UCtagsAspell:dictfile=${dictfile}"
	fi
    done

    for w in $(git log ${commit} \
		   | grep '^[ \t]*CSPELL:' \
		   | sed -e 's/^[ \t]*CSPELL:\(.*\)/\1/'); do
	CTAGS_LOCAL_OPTIONS="${CTAGS_LOCAL_OPTIONS} --param-UCtagsAspell:dictword=${w}"
    done

    printf "checking ${commit}..."
    ${CTAGS} ${CTAGS_OPTION} ${CTAGS_LOCAL_OPTIONS} ${OUTDIR}/${iname}.txt > ${OUTDIR}/${oname}
    nerrors=$(wc -l < "${OUTDIR}/${iname}-misspelling.tags")
    if [ "$nerrors" = 0 ]; then
	echo "ok"
    else
	echo "unknown words"
    fi

    if ! [ "${nerrors}" = 0 ]; then
	cat ${OUTDIR}/${oname} | while read word rest; do
	    echo "	$word"
	done | sort -u
    fi
    total_errors=$(expr "${total_errors}" '+' $nerrors)
    count=$(expr $count '+' 1)
done

if [ "${total_errors}" = 0 ]; then
    exit 0
else
    exit 1
fi
