#!/bin/bash

. /usr/local/bins/common

function usage(){ #{{{{
  cat <<EOF

     $0 [-l(inebreaks] <file>

     Editiert eine csv-Datei in Spaltendarstellung (cf. mycsvview) und speichert das Ergebnis wieder in die 
     unformatierte Originaldatei.

     Cave: mycsvedit kann prinzipiell nicht unterscheiden, ob das Ergebnis einer Editierung Zeilenumbrueche innerhalb von Zellen enthaelt
     
           Feld 1|Feld 2       |    
                 |mit          |
                 |Umbruechen   |
                 |oder mehreren|
                 |Zeilen ?     |

           Ist dies der Fall, werden diese mit Option -l genau dann als solche interpretiert, wenn das erste Feld der jeweiligen Zeile leer ist,
           und nur dann in Pseudozeilenumbrueche (cf. mycsvview) zurueckgewandelt.

           Feld 1|Feld 2       |     => Feld 1;Feld 2\nmit\nUmbruechen\noder mehreren\nZeilen ?
                 |mit          |
                 |Umbruechen   |
                 |oder mehreren|
                 |Zeilen ?     |

           Cave: Hatte die Originaldatei vor Editierung Pseudozeilenumbrueche und wird Option -l nicht angegeben, enthaelt das Ergebnis 
                 echte Zeilenumbrueche

                 Feld 1;Feld 2\nmit\nUmbruechen\noder mehreren\nZeilen ?   =>  Feld 1|Feld 2       |     =>  Feld 1;Feld 2
                                                                                     |mit          |         ;mit
                                                                                     |Umbruechen   |         ;Umbruechen
                                                                                     |oder mehreren|         ;oder mehreren
                                                                                     |Zeilen ?     |         ;Zeilen ?

     -l: Rueckwandlung von Zeilen mit leerem erstem Feld in Pseudozeilenumbrueche des jeweiligen Feldes (cf. oben)

     Zuvor wird von der Original-Datei ein Backup im Unterverzeichnis Revisions angelegt.

     Cave: Die Datei muss bereits im richtigen Zeichensatz (und UNIX-Format) vorliegen.

EOF
} #}}}}
#{{{{ variables
infile=""
backupDir=Revisions
backup=""
linebreaks=""
viewOut=pretty
timeStamp=$(getTimeStamp)
formattedFile=${viewOut}_${timeStamp}
#}}}}
#{{{{ getOpts
while getopts "hl" opt; do
  case $opt in
    h) usage; exit ;;
    l) linebreaks="yes" ;;
    *) die "Keine gueltige Option" ;;
  esac
done
shift $(( OPTIND -1 ))
infile="$1"
#}}}}
#{{{{ verification
[ -z "$infile" ] && die "Keine Datei angegeben"
[[ ! "$infile" =~ \.csv$ ]] && die "Keine csv-Datei $infile"
for file in $infile; do
  verifyFile $file
done
if [ ! -d $backupDir ]; then
  mkdir $backupDir
  checkReturn "mkdir-Fehler"
fi
#}}}}
#-------------------------------------------------------------------------------------------
backup=${infile}_${timeStamp}.bak         # Backup
cp "$infile" ${backupDir}/"$backup"
checkReturn "cp-Fehler"
mycsvview "$infile"                       # Formatieren
checkReturn "mycsvview-Fehler"
mv "$viewOut" "$formattedFile"
checkReturn "mv-Fehler $viewOut => $formattedFile"
vim "$formattedFile"                      # Editieren
#-------------------------------------------------------------------------------------------
# Interpretation von Umbruechen bei leerem erstem Feld als Umbruch innerhalb Feld => Pseudozeilenumbruch ?
#-------------------------------------------------------------------------------------------
if [ -n "$linebreaks" ]; then
  awk '                                     # "Entformatieren"
    function flush(    i, out) {
      if(prevN == 0) return;
      out = prevF[1];
      for(i=2; i<=prevN; i++) out = out ";" prevF[i];
      print out;
      prevN = 0;
    }
    {
      line = $0;
      gsub(/[ ]+\|[ ]+/, "|", line);       # "  |   "      => |
      gsub(/[ ]+\|/,     "|", line);       # "     |"      => |
      gsub(/\|[ ]+/,     "|", line);       # "|     "      => |
      sub(/^\|/, "", line);                # | an Zeilenanfang ...
      sub(/\|$/, "", line);                # | und -ende loeschen
      n = split(line, f, "|");
      if(f[1] == "" && prevN > 0){         # Fortsetzungszeile: erstes Feld leer => mit Vorgaenger zusammenfuehren
        for(i=1;i<=n;i++){
          if(f[i] != ""){
            prevF[i]=prevF[i] "\\n" f[i];
          }
        }
      }
      else{
        flush();
        prevN = n;
        delete prevF;
        for(i=1;i<=n;i++){
          prevF[i]=f[i];
        }
      }
    }
    END{ 
      flush();
    }
  ' $formattedFile > "$infile"              # und implizit Originaldatei mit Editions-Ergebnis ueberschreiben
  checkReturn "awk-Fehler"
else
  sed '                                     # "Entformatieren"
    s/[ ]\+|[ ]\+/|/g                       # "  |   "      => |
    s/[ ]\+|/|/g                            # "     |"      => |
    s/|[ ]\+/|/g                            # "|     "      => |
    s/^|//                                  # | an Zeilenanfang ...
    s/|$//                                  # und -ende loeschen
    s/|/;/g                                 # "|"           => ;
  ' $formattedFile > "$infile"              # und implizit Originaldatei mit Editions-Ergebnis ueberschreiben
  checkReturn "sed-Fehler"
fi
rm "$formattedFile"
checkReturn "rm-Fehler $formattedFile"
commonOut "=> $infile"
#-------------------------------------------------------------------------------------------
diff "$infile" "${backupDir}/$backup"                  # Ergebnisvergleich
#-------------------------------------------------------------------------------------------
commonOut "=> $infile"
