#!/bin/bash

# This script will allow to check for changes in the original
# English docs for languages that use po files for translation.
# It combines the function of the old doc-check and rev-update
# scripts (resulting in the name rev-check :-)

# For each language, the last three revisions for which the
# translation has been updated are saved in a file.
# The current revision of English documents is checked against
# the most recent revisions in this file.

lang=""
default_lang="nl"
file=""

print_usage () {
    echo "Usage: $(basename $0) [options] [language] [file]"
    echo "   TODO: explanation of syntax and options"
}

print_usage_err () {
    print_usage
    exit 1
}

check_parm_lang () {
    # Check that directory exists won't work after conversion to po...
    if [ -d "$1" ] ; then
        lang="$1"
    else
        echo "Info: no valid language specified, using default '$default_lang'"
        if [ -d "$default_lang" ] ; then
            lang="$default_lang"
            return 1
        else
            echo "Error: directory for language '$default_lang' not found"
            print_usage_err
        fi
    fi
    return 0
}

check_parm_file () {
    file=$(echo "$1" | sed "s:^./::" | sed "s:^en/::")
    if [ ! -f "./en/$file" ] ; then
        echo "Error: file '$file' does not exist"
        return 1
    fi
    return 0
}

parse_opts () {
    command="check"
    do_diff=""
    do_all=""
    parm_count=0

    for opt in $@; do
        case "$opt" in
            --update|-u)
                [ $command = "check" ] || print_usage_err
                command="update"
                ;;
            --add|-a)
                [ $command = "check" ] || print_usage_err
                command="add"
                ;;
            --diff|-d)
                do_diff=1
                ;;
            --all|-A)
                do_all=1
                ;;
            --convert)
                [ $command = "check" ] || print_usage_err
                command="convert"
                ;;
            --help|-h)
                print_usage
                exit 0
                ;;
            -*)
                print_usage_err
                ;;
            *)
                parm_count=$(($parm_count + 1))
                if [ $parm_count -eq 1 ] ; then
                    check_parm_lang "$opt"
                    [ $? -ne 0 ] && parm_count=$(($parm_count + 1))
                fi
                if [ $parm_count -eq 2 ] ; then
                    check_parm_file "$opt"
                    [ $? -ne 0 ] && print_usage_err
                fi

                [ $parm_count -gt 2 ] && print_usage_err
                ;;
        esac
        
    done

    [ -z "$lang" ] && check_parm_lang "<none>"

    case $command in
        check)
            [ "$do_all" ] && print_usage_err
            ;;
        convert)
            [ "$do_all" ] && print_usage_err
            if [ -n "$file" ] ; then
                echo "Error: parameter [file] not allowed with --$command option"
                print_usage_err
            fi
            if [ ! -d $lang ] ; then
                echo "Error: directory for language '$lang' not found"
                exit 1
            fi
            ;;
        add|update)
            if [ ! "$do_all" ] && [ -z "$file" ] ; then
                echo "Error: parameter [file] missing, to update all files add --all option"
                print_usage_err
            fi
            if [ "$do_all" ] && [ ! -z "$file" ] ; then
                echo "Error: parameter [file] not allowed with --all option"
                print_usage_err
            fi
            ;;
    esac
}

get_rev () {
    local REV
    REV="$(egrep '^<\!--[[:space:]]*\$Id:' ./en/$1 | \
           sed 's/^.*$Id:[[:space:]]*//' | cut -d " " -f 2)"
    if [ -z "$REV" ] ; then
        echo "Error: could not determine revision of './en/$1'"
        return 1
    fi
    echo "$REV"
    return 0
}

get_trev () {
    local TREV
    [ "$2" = "all" ] && fields="2-" || fields="2"
    TREV="$(egrep "^$1" $rev_file | cut -f $fields)"
    if [ -z "$TREV" ] ; then
        return 1
    fi
    echo "$TREV"
    return 0
}

print_diff () {
    local TREV
    local TREV_PREV=""
    for TREV in $2; do
        [ "$TREV_PREV" ] && echo "Diff against revision $TREV_PREV failed, trying next oldest: $TREV"
        svn diff -r $TREV:$3 ./en/$1
        [ $? -eq 0 ] && break
        TREV_PREV=$TREV
    done
}

check_one () {
    REV=$(get_rev $1)
    [ $? -ne 0 ] && return 9
    TREV=$(get_trev $1)
    if [ $? -ne 0 ] ; then
        echo "$1: N/A -> $REV"
        return 2
    fi

    local RET=0
    if [ ! "$TREV" = "$REV" ] ; then
        RET=1
        echo "$1: $TREV -> $REV"
        if [ "$do_diff" ] ; then
            print_diff $1 "$(get_trev $1 all)" $REV
            echo
        fi
    fi
    return $RET
}

do_check () {
    local RESULT=0
    if [ -n "$file" ] ; then
        check_one $file
        RESULT=$?
    else
        for file in $(find ./en/ -name "*.xml" | sed "s:^./::" | sed "s:^en/::"); do
            check_one $file
            [ $? -eq 1 ] && RESULT=1
        done
    fi
    [ $RESULT -ne 1 ] && echo "No updates found"
}

update_revdata () {
    cp $rev_file $rev_file~
    egrep -v "^$1" $rev_file~ >$rev_file

    # Keep the last three revisions in $rev_file
    local REV
    local counter=1
    echo -n "$1" >>$rev_file
    for REV in $2; do
        echo -en "\t$REV" >>$rev_file
        counter=$(($counter + 1))
        [ $counter -gt 3 ] && break
    done
    echo >>$rev_file
    echo "   Revision updated"
}

update_one () {
    local file=$1
    check_one $file
    if [ $? -eq 1 ] ; then
        update_revdata $1 "$REV $(get_trev $1 all)"
    fi
}

do_update () {
    if [ -n "$file" ] ; then
        update_one $file
    else
        for file in $(find ./en/ -name "*.xml" | sed "s:^./::" | sed "s:^en/::"); do
            update_one $file
        done
    fi
}

do_add_one () {
    if egrep "^$file" $rev_file ; then
        echo "Error: revision data already has '$file'"
        exit 1
    fi

    REV=$(get_rev $1)
    [ $? -ne 0 ] && exit 1

    echo -e "$file\t$REV" >>$rev_file
}

do_add_all () {
    for file in $(find ./en/ -name "*.xml" | sed "s:^./::" | sed "s:^en/::"); do
        if [ -f $rev_file ] && egrep "^$file" $rev_file ; then
            continue
        fi

        REV=$(get_rev $file)
        [ $? -ne 0 ] && continue

        echo -e "$file\t$REV" >>$rev_file
        echo "Added '$file' at $REV"
    done
}

do_convert () {
    for file in $(find ./en/ -name "*.xml" | sed "s:^./::" | sed "s:^en/::"); do
        if [ -f ./$lang/$file ]; then
            REV="$(egrep '^<\!--[[:space:]]*original version:' ./$lang/$file | \
                   sed 's/^.*original version:[[:space:]]*//' | cut -d " " -f 1)"
            if [ -z "$REV" ] ; then
                echo "Warning: no revision comment found for './$lang/$file'"
            else
                echo -e "$file\t$REV" >>$rev_file
            fi
        else
            echo "Warning: file './$lang/$file' not found"
        fi
    done
}


## MAINLINE

[ -d ./po/revdata ] || exit 1

parse_opts "$@"
rev_file=./po/revdata/$lang.dat

if [ "$command" = "convert" ] || \
   ( [ "$command" = "add" ] && [ "$do_all" ] ) ; then
    if [ -s $rev_file ] ; then
        echo "Error: file with revision data already exists"
        exit 1
    fi
else
    if [ ! -s $rev_file ] ; then
        echo "Error: file with revision data does not exist"
        exit 1
    fi
fi

case $command in
    check)
        do_check
        ;;
    update)
        do_update
        ;;
    add)
        [ "$do_all" ] && do_add_all || do_add_one
        ;;
    convert)
        do_convert
        ;;
esac

exit 0
