#! /bin/bash
# kate: space-indent on; indent-width 2; replace-tabs on;

# This script is run from kde-common/makemessages - not useful outside of it

# Note to developers:
#  there are not many comments in this code to avoid to slow down the code
#  So please look also in the svn log to have comments about the code

umask 022

extract_desktop() {
  perl ./scripts/createdesktop.pl --file-list=./$1 --base-dir=$2 > desktop.$$.tmp
  dest=$3
  msguniq --to-code=UTF-8 --no-wrap -o desktop.$$ desktop.$$.tmp 2>/dev/null
  if test -s desktop.$$; then
    python ./scripts/msgsplit desktop.$$
    if test ! -f  $dest; then 
      echo "File $dest is missing!" 
      mv desktop.$$ $dest
    elif diff -q -I^\"POT-Creation-Date: desktop.$$ $dest > /dev/null; then
      rm -f desktop.$$
    else
      mv desktop.$$ $dest
    fi
  else
    echo "Error while trying to create $dest"
  fi
  rm -f desktop.$$ desktop.$$.tmp
}

postprocess_pot_file()
{
# $1: name of the file to process
  mv $1 $1.orig
  sed -e 's,^"Content-Type: text/plain; charset=CHARSET\\n"$,"Content-Type: text/plain; charset=UTF-8\\n", ; s,"Content-Transfer-Encoding: ENCODING\\n","Content-Transfer-Encoding: 8bit\\n", ; s,"Language-Team: LANGUAGE <LL@li.org>\\n","Language-Team: LANGUAGE <kde-i18n-doc@kde.org>\\n",' < $1.orig > $1
  rm -f $1.orig
}

pot_files_diff()
{
# $1 and $2 are the two .pot files to compare
# We do not check: Content-Type, Content-Transfer-Encoding, POT-Creation-Date Language-Team
  diff -q -I^\"POT-Creation-Date: -I^\"Content-T -I^\"Language-Team: $1 $2 > /dev/null
}

update_translations() {
  echo "@@@ Processing branch $transmod ..."
  test -z "$TIMING1" || date

  for i in $releases l10n; do
    test -z "$NOUPDATE" || continue
    test -z "$VERBOSE1" || echo "updating $i"
  
    i=`get_path $i`
    if ! test -d $i; then
      mkdir -p $i
      svn co $SVNROOT/$i $i
    fi
  
    if cd $i; then
      svn cleanup .
      if test "$i" = "l10n"; then
        svn cleanup scripts/admin
        # Cleanup the external documentation directories of l10n
        if cd documentation; then
          for $docdir in *
          do
            svn cleanup $docdir
          done
          cd ..
        else
          echo "Could not cleanup l10n/documentation"
        fi
      elif test -d admin; then
        svn cleanup admin
      fi
      perl $kdebasedir/kdesdk/scripts/svn-clean -f | fgrep -v "Subversion working directory" | grep -v '^F'
      test -z "$VERBOSE1" || echo
      # revert all changes, so that the following "svn update" is without conflicts
      ### TODO: add $SVNQUIETFLAG when the code will be stable
      svn revert -R .
      if test -d admin; then
        svn revert -R admin
      fi
      ### TODO: do we need to revert the external directories of l10n too? (Are we modifying them at all?)
      test -z "$VERBOSE1" || echo
      svn update $SVNQUIETFLAG || echo "ERROR: module $i was not correctly updated"
      cd $BASEDIR
    fi
  done
  
  test -z "$VERBOSE1" || echo "finished updating"
  test -z "$TIMING1" || date
  
  rm -fr backup
  mkdir backup
  ### TODO: try to find a way to still use hardlinks
  cp -a $transmod/templates backup
  
  # Where are the tools needed for message extraction?
  
  extractrc=$kdebasedir/kdesdk/scripts/extractrc
  extractattr=$kdebasedir/kdesdk/scripts/extractattr
  preparetips=$kdebasedir/kdelibs/kdeui/preparetips
  
  kdelibs=

  for templatename in $releases; do
  
    test -z "$NOXGETTEXT" || continue

    logmod=$templatename
    mod=`get_path $templatename`
    rm -rf /tmp/cvslog.$logmod
    if test -f $mod/Makefile.am.in; then
      rm -f $mod/Makefile.am $mod/subdirs 
      ( cd $mod && make -f admin/Makefile.common subdirs Makefile.am )
    fi
    if test -f $mod/Makefile.am; then

      if test ! -d $BASEDIR/$transmod/templates/messages/$templatename; then
        if cd $BASEDIR/$transmod/templates/messages; then
          echo "creating templates directory for $templatename"
          mkdir $BASEDIR/backup/templates/messages/$templatename
          svn mkdir $templatename
          cd $BASEDIR
        else
          echo "SKIPPING $mod - no template directory!"
	  continue
	fi
      fi
  
      if test -z "$kdelibs" -a "$templatename" = "kdelibs"; then
      	kdelibs=$mod
        cp -p $mod/kde.pot backup/kde.pot
      fi
  
      test -z "$VERBOSE1" || echo "making messages in $mod"
      if test ! -d $mod/po; then
        ln -s $BASEDIR/$transmod/templates/messages/$templatename $mod/po
      fi
      ls -d $mod/po
  
      ### TODO: try to find a more simplier way to make these checks for a kde.pot
      includedir=$BASEDIR/$kdelibs
      if ! test -e $includedir/kde.pot; then
        includedir=$BASEDIR/$mod
      fi
      if ! test -e $includedir/kde.pot; then
        includedir=$kdebasedir/kdelibs
      fi
      if test ! -s $includedir/kde.pot; then
          echo "Cannot find $includedir/kde.pot"
      fi
      
      (cd $mod && XGETTEXT=`which xgettext` \
        includedir=$includedir EXTRACTRC="perl $extractrc" EXTRACTATTR="perl $extractattr" PREPARETIPS="perl $preparetips" PACKAGE=$mod bash admin/cvs.sh extract-messages)
      rm -f $mod/messages.log
  
      if test "$mod" = "$kdelibs"; then
        specialfile=$mod/kde.pot
        if pot_files_diff backup/kde.pot $specialfile > /dev/null; then
          cp -f backup/kde.pot $specialfile
        else
          postprocess_pot_file $specialfile
          ( cd $mod; svn commit -m "SVN_SILENT made messages (kde.pot)" $specialfile > /dev/null )
        fi
      fi
  
      (cd $mod &&
        svn commit -q -m "SVN_SILENT made messages (after extraction)" > /dev/null)
      if cd $transmod/templates/messages/$templatename ; then
        for i in *.pot; do
          if test ! -f $i; then continue; fi
          if test ! -f $BASEDIR/backup/templates/messages/$templatename/$i ; then
            postprocess_pot_file $i
            echo "Adding .pot file: $i"
            svn add $i
            cp -f $i $BASEDIR/backup/templates/messages/$templatename/$i
          elif pot_files_diff $i $BASEDIR/backup/templates/messages/$templatename/$i > /dev/null ; then
            if test `stat -c %Y $i` -lt $STARTTIME; then
              cp -f -p $BASEDIR/backup/templates/messages/$templatename/$i $i
            else
              cp -f $BASEDIR/backup/templates/messages/$templatename/$i $i
            fi
          else
            postprocess_pot_file $i
            cp -f $i $BASEDIR/backup/templates/messages/$templatename/$i
          fi
        done
        cd $BASEDIR
      fi
      rm -rf $mod/po.backup
      if test -L $mod/po; then rm -f $mod/po; fi
    else
      echo "ERROR: no Makefile.am generated for $templatename"
    fi
  
  done
  
  test -z "$VERBOSE1" || echo "updating files in $transmod"
  if cd $transmod; then
    rm -f statuslist.tmp
    test -z "$VERBOSE1" || echo "adding missing templates"
    test -z "$TIMING1" || date
    list=`find templates/messages -name '*.pot'`
    for i in $list; do
      if test ! -f $BASEDIR/backup/$i; then
        postprocess_pot_file $i
        echo "Adding .pot file: $i (late)"
        svn add $i;
        cp -f $i $BASEDIR/backup/$i
      elif pot_files_diff $i $BASEDIR/backup/$i > /dev/null ; then
        stat -c "%Y %n" $i >> statuslist.tmp
        cp -fp $BASEDIR/backup/$i $i
      else
        postprocess_pot_file $i
        cp -f $i $BASEDIR/backup/$i
      fi;
    done
    test -z "$VERBOSE1" || echo "committing l10n/templates/messages"
    test -z "$TIMING1" || date
    svn commit -m "SVN_SILENT made messages (.pot file)" templates/messages > /dev/null
    if test -z "$NOXGETTEXT"; then
       echo "Potentially obsolete .pot files:"
       perl -n -e "use POSIX qw(strftime); /([0-9]+) (.+)/; if ( \$2 =~ m/\/desktop_.+\.pot/ ) {} elsif ( \$1 < $STARTTIME ) { print strftime (\"%Y-%m-%d\", gmtime(\$1)).\" \".\$2. \"\n\";}" < statuslist.tmp | sort
       echo "--- end of list ---"
    fi
    rm -f statuslist.tmp
    test -z "$VERBOSE1" || echo "reupdating l10n/templates/messages"
    test -z "$TIMING1" || date
    svn revert $SVNQUIETFLAG -R templates/messages
    svn update $SVNQUIETFLAG templates/messages | egrep -v "^(U | U|UU)"
    # Note the -type f in the following find is needed to exclude the names of the "pruned" directories
    find templates/messages \( -name .svn -prune -o -name "*.pot" \) -type f -printf "%f\\n" | sort | uniq -d > templatenames.tmp
    if test -s templatenames.tmp; then
      echo "ERROR: there are duplicated POT files:"
      cat templatenames.tmp
      echo "--- end duplicated POT files ---"
    fi
    rm -f templatenames.tmp
    
    test -z "$VERBOSE1" || echo "creating desktop*.pot files"
    test -z "$TIMING1" || date
    bash scripts/findfiles ./all_files 

    for mod in $releases l10n; do
    	case "$mod" in
		extragear-*)
			basedir=$BASEDIR/`get_path $mod`
			subdirs=`grep $basedir all_files_$mod | sed -e "s,$basedir/,," | cut -d/ -f1`
			for subdir in $subdirs; do
				mods="$mod""_$subdir"
				grep $basedir/$subdir all_files_$mod > all_files_$mods
			        extract_desktop all_files_$mods $basedir/$subdir templates/messages/$mod/desktop_$mods.pot
			done				
			rm -f all_files_$mod
			;;
		l10n)
			extract_desktop all_files_$mod $BASEDIR/`get_path $mod` templates/messages/kdelibs/desktop_l10n.pot
			;;
		*)
			extract_desktop all_files_$mod $BASEDIR/`get_path $mod` templates/messages/$mod/desktop_$mod.pot
			;;
	esac
    done

    test -z "$VERBOSE1" || echo "commiting desktop*.pot files"
    test -z "$TIMING1" || date
    if cd templates/messages; then
      list=`find . -name desktop\*.pot`
      # desktop*.pot files have already a correct Content-Type, so we do not need to check it or even to modify it
      for i in $list; do
        if test ! -f $BASEDIR/backup/templates/messages/$i; then
          echo "Adding desktop*.pot file: $i"
          svn add $i;
        elif pot_files_diff $i $BASEDIR/backup/templates/messages/$i > /dev/null ; then
          cp -f $BASEDIR/backup/templates/messages/$i $i
        fi
      done
      svn commit -m "SVN_SILENT made messages (desktop*.pot file committed)" > /dev/null
      cd ../..
    fi
    
    rm -fr $BASEDIR/backup
    
    test -z "$VERBOSE1" || echo "checking svn:executable in l10n"
    test -z "$TIMING1" || date
    # try to find all "executable" PO, POT, PNG, JPEG, DocBook, WAV, OGG files and remove the svn:executable property
    find . \( -name .svn -o -name documentation \) -prune , -type f \( -name \*.po -o -name \*.pot -o -name \*.png -o -name \*.jpeg -o -name \*.jpg -o -name \*.docbook -o -name \*.wav -o -name \*.ogg \) -perm -u+x | xargs --no-run-if-empty svn propdel svn:executable
    svn commit $SVNQUIETFLAG -m "SVN_SILENT made messages (svn:executable)"
    test -z "$VERBOSE1" || echo "reupdating l10n"
    test -z "$TIMING1" || date
    svn cleanup
    svn update $SVNQUIETFLAG | egrep -v "^(U | U|UU)"
    # clear conflicts by using "svn revert"
    svn revert -R .
    test -z "$VERBOSE1" || echo "merging"
    test -z "$TIMING1" || date
    echo
    echo "%% TRANSLATOR START $transmod"
    echo
    sh scripts/merge_all.sh
    echo
    echo "%% TRANSLATOR END $transmod"
    echo
    test -z "$VERBOSE1" || echo "Preparing to commit new files"
    test -z "$TIMING1" || date
    # SVN 1.2.3: svn status without parameters has not changed its output format
    list=`svn status | fgrep -v "Performing" | cut -b8-`
    for i in $list; do
      if test ! -s $i; then
        svn revert $SVNQUIETFLAG $i
      fi
    done
    # Note: we assume here that names of PO files never start with a digit
    # SVN 1.2.3: svn stat -u has still the modified-on-server flag at the 8th column, followed by a revision number and the file name
    svn status --show-updates | perl -n -e "if ( /^Performing/ ) { } elsif ( /^.{7}\*\s+[0-9]*\s+([^0-9].+)/ ) { print \$1.\"\n\"; }" > ../conflicts.tmp
    if test -s ../conflicts.tmp; then
      for i in `cat ../conflicts.tmp`; do
        if test -f $i; then
          test -z "$VERBOSE" || echo "File was updated on server: $i"
          svn revert $SVNQUIETFLAG $i
        elif test -d $i; then
          echo "Directory was updated on server: $i"
          ### Temporary
          svn status --show-updates $i
          # If the file was modified locally and on the server, we have to revert the local change
	  # Note: we assume here that names of PO files never start with a digit
          ### TODO: what about property changes on server
	  # SVN 1.2.3: svn stat -u has still the modified flag at the 1st column, the modified-on-server flag at the 8th column, followed by a revision number and the file name
          svn status --show-updates $i | perl -n -e "if ( /^Performing/ ) { } elsif ( /^M.{6}\*\s+[0-9]*\s+([^0-9].+)/ ) { print \$1.\"\n\"; }" > ../dir_conflicts.tmp
          fgrep -v .svn ../dir_conflicts.tmp | xargs --no-run-if-empty rm -v 
          svn update $SVNQUIETFLAG $i
        elif test ! -e $i; then
          # We do not know the file yet, so no need to do anything 
          echo "New file on server: $i"
        else
          # As we do not know what we got, try to get as much information as possible
          echo "Unknown file type, updated on server: $i"
          svn status --verbose --show-updates $i
          svn revert $i
        fi
      done
    fi
    rm -f ../conflicts.tmp ../dir_conflicts.tmp
    test -z "$VERBOSE1" || echo "commiting new files"
    test -z "$TIMING1" || date
    if ! svn commit -m "SVN_SILENT made messages (.po file)" > /dev/null; then
      test -z "$VERBOSE1" || echo "commiting new files, second try"
      test -z "$TIMING1" || date
      ### TODO: find a good way to avoid using the subdirs file
      for i in `cat subdirs`; do
        if cd $i; then
          if ! svn commit $SVNQUIETFLAG -m "SVN_SILENT made messages (.po file, second try)"; then
            echo "Could not commit l10n/$i . Reverting!"
            svn revert -R .
          fi
	  cd ..
        else
          echo "Cannot commit, unknown directory l10n/$i"
        fi
      done
    fi
    cd $BASEDIR
  fi

  if true; then
    if cd $transmod; then
      test -z "$VERBOSE1" || echo "applying desktop file translations"
      test -z "$TIMING1" || date
      g++ -O2 -march=pentium2 -o apply scripts/apply.cc
      bash scripts/merge_desktop_files.sh 
      cd $BASEDIR
    fi
    test -z "$VERBOSE1" || echo "commiting desktop files"
    test -z "$TIMING1" || date
    for i in $releases l10n; do
      if cd $BASEDIR/`get_path $i`; then
        ### TODO Correct conflict management
        if ! svn commit -m "SVN_SILENT made messages (.desktop file)" > /dev/null; then
          # If the commit fails, then it means that a file was modified. Normally it will not be a .desktop file
          echo "Need to update $i"
          svn update $SVNQUIETFLAG
          svn commit $SVNQUIETFLAG -m "SVN_SILENT made messages (.desktop file, second try)"
        fi
      fi
    done
  else
    echo "Skipping processing of .desktop files"
  fi

  rm -rf apply all_files* messages
  cd $BASEDIR
  echo "@@@ branch $transmod processed!"
  test -z "$TIMING1" || date
}

# releases: paths of modules - kdelibs has to be first
# transmod: path of the corresponding l10n module

# test only
dir=`dirname $0`
. $dir/get_paths
transmod=`get_path l10n`
releases=`list_modules`
# $kdebasedir is the path to find utilities in kdelibs or kdesdk (and as fallback for kdelibs/kde.pot)
kdebasedir=$BASEDIR/`kde_base_dir`
update_translations
