#!/bin/bash

# copyright (c) 2005, 2006 Erik Jan Tromp <alphageek@slackware.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# Version 2 as published by the Free Software Foundation
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See the GNU General Public License for more details.
#
#	http://www.fsf.org/licenses/gpl.html

usage()
{
  cat << EOF

this is a test of the emergency broadcast system.

had this been a real emergency, you'd be dead.

thank you & have a nice day!

EOF
exit 1
}


# parse 3 non-optional & 1 optional parameter(s):
# --isopath,-i = full path to isos (matched to tree), requires '//' separator
# --treepath,-t = full path to tree (matched to isos), requires '//' separator
# --workpath,-w = full path to .jigdo/.template/.meta save dir
# --verbose,-v = gee, what could this mean?
unset ISOPATH TREEPATH WORKPATH
VERBOSE="quiet"
while [ $# -gt 0 ] ; do
  case "$1" in
    --isopath|-i)
      shift
      ISOPATH=${1/%\//}
      shift
      ;;
    --treepath|-t)
      shift
      TREEPATH=${1/%\//}
      shift
      ;;
    --workpath|-w)
      shift
      WORKPATH=${1/%\//}
      shift
      ;;
    --verbose|-v)
      VERBOSE="default"
      shift
      ;;
    *)
      usage
      ;;
  esac
done

# rudimentary sanity checks
if [ -z "$ISOPATH" ] ; then
  echo "iso path not specified. aborting"
  usage
fi
if [ ! -d "$ISOPATH" ] ; then
  echo "iso path does not exist. aborting"
  usage
fi
if [ -z "`echo $ISOPATH | grep //`" ] ; then
  echo "iso path requires \"//\" separator. aborting"
  usage
fi
if [ -z "$TREEPATH" ] ; then
  echo "tree path not specified. aborting"
  usage
fi
if [ ! -d "$TREEPATH" ] ; then
  echo "tree path does not exist. aborting"
  usage
fi
if [ -z "`echo $TREEPATH | grep //`" ] ; then
  echo "tree path requires \"//\" separator. aborting"
  usage
fi
if [ -z "$WORKPATH" ] ; then
  echo "work path not specified. aborting"
  usage
fi
if [ ! -d "$WORKPATH" ] ; then
  echo "work path does not exist. aborting"
  usage
fi


# we need this for jigdo-file specific magic, hence the //'s
ISOSUFFIX=`echo $ISOPATH | sed 's,.*//,,'`
TREEPREFIX=`echo $TREEPATH | sed 's,//.*,,'`


make_template()
{
  [ "$VERBOSE" = "default" ] && echo "processing: $ISONAME.iso"

  find $TREEPATH/ -type f -size +255c \
  | egrep -v "^$TREEPATH/patches/|\.iso$" \
  | sort \
  | jigdo-file make-template --files-from - \
  --force --min-length 256 --no-greedy-matching \
  --no-servers-section --report $VERBOSE \
  --jigdo $WORKPATH/$ISONAME.jigdo \
  --template $WORKPATH/$ISONAME.template \
  --image $ISOPATH/$ISONAME.iso \
  --label Slackware=$TREEPREFIX

  # post-processing

  # tweak image path & timestamp
  sed -i "s,Filename=,Filename=$ISOSUFFIX/, ; \
  /^Template=/iFiletime=`date -ur $ISOPATH/$ISONAME.iso`" \
  $WORKPATH/$ISONAME.jigdo

  # create .meta file (size, date, path) for faster rebuilds
  # pardon the loop, but we can't guarantee a short enough list
  # for find to deal with (think: dvds)
  sed -n '/\[Parts\]/,/^$/{s,.*:,,p}' $WORKPATH/$ISONAME.jigdo \
  | while read TREESUFFIX ; do
    find $TREEPREFIX/$TREESUFFIX -printf %s\\t%T@\\t$TREESUFFIX\\n
  done > $WORKPATH/$ISONAME.meta

  # set timestamps of .jigdo/.template/.meta to match tree's changelog date
  # (mostly cosmetic. handy when trying to figure out how old stuff is)
  touch $WORKPATH/$ISONAME.{jigdo,template,meta} \
  --date "`head -n1 $TREEPATH/ChangeLog.txt`" 2> /dev/null
}


for ISONAME in `find $ISOPATH/ -type f -name '*.iso' \
| sed "s,$ISOPATH/,, ; s,\.iso,," | sort` ; do

  # the complete fileset doesn't exist, create
  if [ ! -r "$WORKPATH/$ISONAME.jigdo" -o \
  ! -r "$WORKPATH/$ISONAME.template" -o \
  ! -r "$WORKPATH/$ISONAME.meta" ] ; then
    make_template

  # the fileset may be out of date, test & rebuild as required
  # simplistic, but extremely fast test. regenerate .meta & compare
  # against original. there's a moderate probability that the fileset
  # will be redundantly rebuilt, but it's more than offset by the time
  # saved over many iterations (think: automated mirroring)
  else

    # create duplicate .meta file (size, date, path) for faster comparison
    sed -n '/\[Parts\]/,/^$/{s,.*:,,p}' $WORKPATH/$ISONAME.jigdo \
    | while read TREESUFFIX ; do
      find $TREEPREFIX/$TREESUFFIX -printf %s\\t%T@\\t$TREESUFFIX\\n 2> /dev/null
    done > $WORKPATH/$ISONAME.meta.tmp

    cmp -s $WORKPATH/$ISONAME.meta{,.tmp}
    EXITSTATUS=$?
    rm $WORKPATH/$ISONAME.meta.tmp

    # size or date differ (on at least 1 file)
    [ $EXITSTATUS -ne 0 ] && make_template
  fi
done
