#!/bin/bash
# -*- coding:utf-8 -*-
# file KLEIDER/web/src/localization/runonce
# 2015-10-06 Herbert Schiemann <h.schiemann@herbaer.de>
# Programm zur einmaligen Anwendung im Zusammenhang mit der Übersetzung
# als Vorlage für andere Einmal-Programme

# Zähler, Variable, Aktionen
declare_vars ()
{
   # Ein Leerzeichen als Wert bedeutet, dass Positionsargumente verarbeitet werden
   _argv=" ";

   # Suchpfad für rc-Dateien, : - getrennte Liste von Verzeichnispfaden
   # Falls leer, wird die Option --rc nicht speziell behandelt
   g_configpath= ;

   # Zähler
   g_counters=" \
    verbose     \
    overwrite   " ;

   # Variable
   g_variables=" \
     srcdir      \
     trlang      \
     srclang     ";

   # Aktionen
   g_actions="" ;
} # declare_vars

# setzt Vorgabe-Werte
set_defaults ()
{
   [[ -n $overwrite ]] || overwrite=0 ;
   if [[ -z $srcdir ]]; then
      srcdir=$(realpath $0);
      srcdir=${srcdir#/*};
   fi;
   [[ -n $srclang   ]] || srclang=de ;
} # set_defaults

# Zeigt eine kurze Hilfe an
show_help ()
{
   local cmd=${0#*/} ;
   set_defaults ;
   cat << .HELP ;
$cmd --version
$cmd --help
$cmd [Option]*  FILE ..

FILE                  Rel. Pfad einer zu übersetzenden Datei ohne Sprachsuffix
                      ($_argv)
Optionen
--[no_]verbose        Erhöht den Umfang der Ausgabe des Scripts ($verbose)
--[no_]overwrite      Existierende Dateien überschreiben ($overwrite)
--srcdir SRCDIR       Verzeichnis der Skripte
                      ($srcdir)
--trlang TRLANG       Zielsprachen ($trlang)
--srclang SRCLANG     Kürzel der Ausgangssprache ($srclang)
.HELP
} # show_help

# Zeigt die Version an
show_version ()
{
   cat << .VERSION ;
$0
Programm zur einmaligen Anwendung im Zusammenhang mit Lokalisierungen
2015-10-06, Herbert Schiemann, h.schiemann@herbaer.de
GPL Version 2 oder neuer
.VERSION
} # show_version

# Variable und Zähler initialisieren
init_vars () {
   local v;
   declare_vars ;
   for v in $g_counters $g_variables $g_actions; do
      eval "$v=" ;
   done;
} # init_vars

# Argumente verarbeiten
read_args ()
{
   local wd ;
   local lastwd ;
   local var ;
   local ok ;

   has_actions=0 ;
   for wd in "$@"; do
      if [[ "$lastwd" = "--" ]]; then
          _argv="$_argv $wd";
      elif [[ -n "$lastwd" ]]; then
         if [[ "$wd" =~ ^[\ a-zA-Z0-9./_#-]+$ ]]; then
            if [[ "$lastwd" == "rc" && -n "$g_configpath" ]]; then
               if ! read_configuration $wd; then
                  (( verbose )) && echo "Kann Konfiguration $wd nicht lesen" ;
                  exit 10 ;
               fi ;
            else
               ok=0 ;
               for var in $g_variables; do
                  if [[ "$var" == "$lastwd" ]]; then
                     (( ++ok )) ;
                     eval "$var=\"$wd\"" ;
                     break ;
                  fi ;
               done ;
               if (( ! ok )); then
                  (( verbose )) && echo "Unbekannte Option --$lastwd $wd" ;
                  exit 11 ;
               fi ;
            fi ;
         else
            (( verbose )) && echo "Ungültiger Optionswert --$lastwd $wd" ;
            exit 12;
         fi;
         lastwd= ;
      else
         case "$wd" in
            --version )
               show_version ;
               exit 0 ;
               ;;
            --help )
               show_version ;
               show_help ;
               exit 0 ;
               ;;
            -- )
               if [[ -n "$_argv" ]]; then
                  lastwd=--;
                  continue;
               else
                  (( verbose )) && echo "Ungültige Option $wd" ;
                  exit 13 ;
               fi ;
               ;;
            --* )
               if [[ "$wd" =~ ^--[a-z][a-z0-9_]*$ ]]; then
                  lastwd=${wd#--} ;
                  ok=0 ;
                  for var in $g_counters ; do
                     if   [[ "$lastwd" == $var    ]]; then
                        eval "(( ++$lastwd ))" ;
                     elif [[ "$lastwd" == "no_$var" ]]; then
                        eval "${lastwd#no_}=0" ;
                     else
                        continue;
                     fi;
                     (( ++ok )) ;
                     break ;
                  done;
                  if (( !ok )); then
                     for var in $g_actions; do
                        if [[ "$lastwd" == "$var" ]]; then
                           eval "(( ++$var ))" ;
                           (( ++ok ));
                           has_actions=1;
                           break;
                        elif [[ "$lastwd" == "no_$var" ]]; then
                           eval "(( ++no_$var ))" ;
                           (( ++ok ));
                           break;
                        fi;
                     done;
                  fi;
                  (( ok )) && lastwd=;
               else
                  (( verbose )) && echo "Ungültige Option $wd" ;
                  exit 14 ;
               fi ;
               ;;
            * )
               if [[ -n $_argv ]]; then
                   _argv="$_argv $wd";
               else
                   (( verbose )) && echo "Ungültige Option $wd" ;
                   exit 15 ;
               fi;
               ;;
         esac ;
      fi ;
   done ;
   if [[ -n $lastwd && "$lastwd" != "--" ]]; then
      (( verbose )) && echo "Unverarbeitete Option --$lastwd";
      exit 16 ;
   fi ;
   [[ "$_argv" =~ ^[[:space:]]+$ ]] && _argv="" ;
} # read_args

# Aktionen ausführen
run_actions ()
{
   local act ;
   for act in $g_actions; do
     eval "(( ! has_actions && ! no_$act || $act )) && process_$act";
   done;
} # run_actions

# show_variables VARNAME1 VARNAME2
# Werte der Variablen anzeigen
show_variables ()
{
   local v ;
   for v in $g_counters $g_variables $g_actions $1; do
      eval "echo \"$v = \$$v\"" ;
   done;
} # show_variables

# Können die Eingabedateien gelesen werden?
# check_infiles first/path/to/file path/to/second_file ;
check_infiles ()
{
   local f ;
   for f in "$@"; do
      if [[ ! -f "$f" ]]; then
         (( verbose )) && echo "\"$f\" ist keine gewöhnliche Datei";
         return 1;
      fi;
      if [[ ! -s "$f" ]]; then
         (( verbose )) && echo "\"$f\" ist leer";
         return 1;
      fi;
      if [[ ! -r "$f" ]]; then
         (( verbose )) && echo "Kann Datei \"$f\" nicht lesen";
         return 1;
      fi;
   done;
   return 0;
} # check_infiles

# Können die Ausgabedateien erstellt werden?
# erstellt fehlende Verzeichnisse und löscht existierende Dateien
# nach Maßgabe der Variablen overwrite
# check_outfiles first/path/to/file path/to/second_file ;
check_outfiles ()
{
   local fp;
   local dir;
   local verb;
   (( verbose )) && verb=--verbose ;
   for fp in "$@"; do
      if [[ ! -e $fp ]]; then
         dir=${fp%/*};
         if [[ -n $dir && ! -e $dir ]]; then
            mkdir -p $verb $dir ;
            if [[ ! -d $dir ]]; then
               (( verbose )) && echo "$dir ist kein Verzeichnis";
               return 1;
            fi;
         fi;
      elif [[ -d $fp ]]; then
         (( verbose )) && echo "$fp ist ein Verzeichnis";
         return 1;
      elif (( overwrite )); then
         (( verbose )) && echo "lösche $fp";
         rm $fp;
      else
         (( verbose )) && echo "$fp existiert";
         return 1;
      fi;
      (( verbose )) && echo "$fp";
   done;
   return 0;
} # check_outfiles

# Sind die Dateien ausführbar?
# check_executeable first/path/to/script path/to/second_srcipt ;
check_executeable ()
{
   local f ;
   for f in "$@"; do
      if [[ ! -f "$f" ]]; then
         (( verbose )) && echo "$f\" ist keine gewöhnliche Datei";
         return 1;
      fi;
      if [[ ! -x "$f" ]]; then
         (( verbose )) && echo "$f\" ist keine ausführbare Datei";
         return 1;
      fi;
   done;
   return 0;
} # check_executeable

# Sicherheit
export PATH=/bin:/usr/bin ;
IFS=$' \t\n' ;

init_vars ;

set -o noclobber ;   # existierende Dateien werden nicht versehentlich überschrieben
shopt -s extglob nullglob ;

read_args "$@" ;
set_defaults ;

(( verbose > 1 )) && show_variables;

# hier folgt die auszuführende Aktion
for file in $_argv; do
   if check_infiles $file;
   then
      xmlns=$(xsltproc $srcdir/xmlnsss.xslt $file);
      xmlns=${xmlns%|*}
   else
      xmlns=unknown ;
   fi;
   if [[ $xmlns == "http://herbaer.de/xmlns/20141210/localization" ]]; then
      posttrans=$srcdir/local_post.xslt ;
   else
      posttrans= ;
   fi;
   b=${file%.$srclang.} ;
   if (( verbose )); then
      verb=--verbose ;
   else
      verb= ;
   fi;
   for lang in $trlang; do
      (( verbose )) && echo "LANG $lang";
      f=$b.$lang. ;
      if check_infiles $f; then
         f2=$f.2 ;
         if [[ -n $posttrans ]]; then
            xsltproc $posttrans $f | $srcdir/rmxmlns.pl $verb > $f2 ;
         else
            cat $f | $srcdir/rmxmlns.pl $verb > $f2 ;
         fi;
         if diff $f $f2 > /dev/null 2>&1 ; then
            (( verbose )) && echo "NOCHNG $f";
            rm $f2;
         else
            rm $f;
            mv $f2 $f;
            [[ -f $f.gz ]] && rm $f.gz ;
            gzip --best --stdout $f > $f.gz ;
         fi;
      fi;
   done;
done;

exit 0;
# end of file KLEIDER/web/src/localization/runonce
