#! /bin/sh
#------------------------------------------------------------------------------
#$Author: saulius $
#$Date: 2023-01-23 09:51:08 +0000 (Mon, 23 Jan 2023) $
#$Revision: 10378 $
#$URL: file:///home/saulius/svn-repositories/paskaitos/VU/software/assignment-evaluation/trunk/scripts/merge-moodle-grading-worksheet $
#------------------------------------------------------------------------------
#*
# Merge grades generated by the Makefile from the comments.txt files into a
# Moodle grading worksheet (CSV format).
#
# Input format of the 'evaluation.lst' file:

## # 2018-04-01 17:11:26 EEST
## 75/85   Saulius Gražulis -- preliminarus įvertinimas.  Komentarai faile 'comments.txt'
## 25/85   Vardauskas Studentauskas -- preliminarus įvertinimas.  Komentarai faile 'comments.txt'

# The grades (the first column) and student's name is separated by a
# single TAB character (ASCII 09). The sutdent's name is followed by a
# ' --' sequence (space + two hyphens). This sequence, if present, and
# everything that follows it is ignored.

# Input format of the 'Grades*.csv' file:

## Identifier,"Full name","Email address",Status,Grade,"Maximum Grade","Grade can be changed","Last modified (submission)","Last modified (grade)"
## "Participant 256","Saulius Gražulis",sg@domain.lt,"Submitted for grading - Extension granted until: Tuesday, 20 March 2018, 12:00 PM",,100.00,Yes,"Tuesday, 20 March 2018, 11:29 AM","Tuesday, 20 March 2018, 11:29 AM"
## "Participant 268","Vardauskas Studentauskas",vs@domain.com,"Submitted for grading - Extension granted until: Tuesday, 20 March 2018, 12:00 PM",,100.00,Yes,"Tuesday, 20 March 2018, 11:39 AM","Tuesday, 20 March 2018, 11:39 AM"

# The first line contains column names and will be ignored.
#
# Student name is taken from the 2-nd comma-separated column and will be used
# for joining the two files.
#
# Grade (the first number in the 'evaluation.lst' file) will be inserted into
# the 5-th column of the work-sheet.

#**

TMP_DIR="${TMPDIR}"

set -ue
## set -x

script() { echo "# $*"; cat; }
setvar() { eval $1="'$3'"; }

setvar Id = '$Id: merge-moodle-grading-worksheet 10378 2023-01-23 09:51:08Z saulius $'

setvar FILES = ""

setvar BASENAME = "$(basename $0)"

#** USAGE:
#**   $0 --options evaluation.lst Grades-Moodle_course-assignment-120.csv
#**
#** OPTIONS:
#**  --help                   print short help message (this message) and exit
while [ $# -gt 0 ]
do
    case $1 in
        --version|--versio|--versi|--vers|--ver|--ve|--v)
            echo $Id
            exit
            ;;
        --help|--hel|--he|--h)
            awk '/#\*/,/#\*\*/ {
                    sub("^ *#[*]?[*]?", ""); \
                    gsub("\\$0","'$0'"); \
                    print $0
                }' $0
	    exit
	    ;;
        --options|--option)
            echo "$0: '--options' is a place-holder; " \
                 "please use '$0 --help' to get the list of available options."
            exit 2
            ;;
        -*) echo "$0: unknown option '$1'" >&2 ; exit 1 ;;
        *)  FILES="$FILES '$1'" ;;
    esac
    shift
done

## echo ${FILES}
eval set -- "${FILES}"

EVALUATION="$1"
GRADE_BOOK="$2"

test -z "${TMP_DIR}" && TMP_DIR="/tmp"
TMP_DIR="${TMP_DIR}/tmp-${BASENAME}-$$"
mkdir "${TMP_DIR}"

TMP_EVALUATION_TAB="${TMP_DIR}/evaluation.tab"
TMP_GRADE_BOOK_TAB="${TMP_DIR}/gradebook.tab"
TMP_MERGED_TAB="${TMP_DIR}/merged.tab"
TMP_NORMALISED_TAB="${TMP_DIR}/normalised.tab"

# To make the trap portable between bash and dash, we need to trap
# "signal" 0 ("EXIT") and rely on it for the cleanup:
## trap "rm -rf '${TMP_DIR}'" 0 1 2 3 15
trap "rm -rf '${TMP_DIR}'" EXIT
trap "exit 1" HUP INT QUIT TERM

## set -x

sed 's/ --.*$//' ${EVALUATION} \
| sed 's/\//\t/' \
| grep -v '^#' \
| perl -CS \
       -MUnicode::Normalize \
       -ne 'chomp;
            @F = split( "\t", $_ );
            $latin_name = $F[2];
            $latin_name =~ s/\s+--\s+.*$//; 
            $latin_name =~ s/^\s*|\s*$//g; 
            $latin_name =~ s/\s/_/g; 
            $latin_name =~ s/-/_/g;
            $latin_name =~ s/__*/_/g;
            $latin_name = NFD($latin_name);
            $latin_name =~ s/[^\0-\x80]//g;
            print uc($latin_name), "\t", $_, "\n"' \
| sort -t "$(echo "\t")" -k 1,1 \
> ${TMP_EVALUATION_TAB}

## echo ===  ${TMP_EVALUATION_TAB} ===; cat ${TMP_EVALUATION_TAB}

cat "${GRADE_BOOK}" \
| perl -CS \
     -MText::CSV \
     -MUnicode::Normalize \
     -lne '
         $csv = Text::CSV->new();
         $csv->parse( $_ );
         my @values = map {s/[\t\r\n]/ /g; $_} $csv->fields();
         my $latin_name = $values[1];
         $latin_name =~ s/^\s*|\s*$//g; 
         $latin_name =~ s/\s/_/g; 
         $latin_name =~ s/-/_/g;
         $latin_name =~ s/__*/_/g;
         $latin_name = NFD($latin_name);
         $latin_name =~ s/[^\0-\x80]//g;
         $latin_name = uc($latin_name);
         unshift( @values, $latin_name );
         $, = "\t";
         print @values;
     ' \
| tail -n +2 \
| sort -t "$(echo "\t")" -k 1,1 \
> ${TMP_GRADE_BOOK_TAB}

## echo ===  ${TMP_GRADE_BOOK_TAB} ===; cat ${TMP_GRADE_BOOK_TAB}

join -t "$(echo "\t")" \
     -1 1 \
     -2 1 \
     ${TMP_EVALUATION_TAB} \
     ${TMP_GRADE_BOOK_TAB} \
> ${TMP_MERGED_TAB}

## echo ===  ${TMP_MERGED_TAB} ===; cat ${TMP_MERGED_TAB}

awk -F"\t" '{OFS="\t"; \
             if( NF == 15 ) { \
               print $5,$6,$7,$8,$9, \
                     int($2*$11/$3<$11 ? ($2 < 0 ? 0 : $2*$11/$3) : $11), \
                     int($11),$12,$13,$14,$15 \
             } else 
             if( NF > 13 ) { \
               print $5,$6,$7,$8, \
                     int($2*$10/$3<$10 ? ($2 < 0 ? 0 : $2*$10/$3) : $10), \
                     int($10),$11,$12,$13,$14 \
             } else { \
               print $5,$6,$7,$8, \
                     int($2*$10/$3<$10 ? ($2 < 0 ? 0 : $2*$10/$3) : $10), \
                     int($10),$11,$12,$13 \
             } \
            }' \
    ${TMP_MERGED_TAB} \
> ${TMP_NORMALISED_TAB}

## echo ===  ${TMP_NORMALISED_TAB} ===; cat ${TMP_NORMALISED_TAB}

perl -CS \
     -MText::CSV \
     -le '
         my $csv = Text::CSV->new( { binary => 1 } );

         open my $fh, "<:encoding(utf8)", $ARGV[0] or 
            die "can not open file \"$ARGV[0]\" for reading: $!";

         my $row = $csv->getline( $fh );
         $csv->print( \*STDOUT, $row );
     ' \
"${GRADE_BOOK}"

awk -F"\t" '{
    ORS=""
    sep=""
    for( i = 1; i <= NF; i++ ) {
        if( match( $i, "," ) || match( $i, " " )) {
            print sep "\"" $i "\""
        } else {
            print sep $i
        }
        sep = ","
    }
    print "\n"
}' ${TMP_NORMALISED_TAB}
