#!/bin/sh -eu

# vorbistagedit -- allows batch editing of vorbis comments with an editor
#
# Copyright © martin f. krafft <madduck@madduck.net>
# Released under the terms of the Artistic Licence 2.0
#
# $Id$
#

VERSION=0.4
ME=${0##*/}

versioninfo() {
  echo "vorbistagedit $VERSION" >&2
  echo "\$Id$" >&2
  echo "$ME is copyright © martin f. krafft" >&2
  echo Released under the terms of the Artistic Licence 2.0 >&2
}

usage() {
  versioninfo
  echo
  echo Usage: $ME file1.ogg [file2.ogg [file3.ogg ...]] >&2
  echo
  echo If no filenames are given, the list of filenames >&2
  echo is read from stdin, one per line. >&2
}

for opt in $(getopt -n $ME -l version,help -o Vh? -- $@); do
  case $opt in
    --version|-V)
      versioninfo
      exit 0;;
    --help|-h|-\?)
      usage
      exit 0;;
    --) :;;
    -*)
      echo "E: $ME: invalid argument: $opt" >&2
      exit 1;;
    *) :;;
  esac
done

if ! command -v vorbiscomment >/dev/null; then
  echo "E: $ME: vorbiscomment not found in \$PATH." >&2
  exit -1
fi

old_IFS="$IFS"
IFS="
"
[ $# -eq 0 ] && set -- $(cat)
IFS="$old_IFS"

if [ $# -eq 0 ]; then
  exit 0
fi

TMPFILE=$(mktemp /tmp/vorbistagedit.XXXXXX)
trap "rm -f $TMPFILE" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

cat <<_eof > $TMPFILE
# vorbistagedit (\$Id$)
#
# Edit the lines in this file to your desire, but
# DO NOT touch lines starting with a colon (:)!
#
# We are in directory:
#  $(pwd)

_eof

for i in "$@"; do
  case "$i" in
    *.ogg)
      if [ ! -r "$i" ]; then
        echo "E: $ME: unreadable file: $i" >&2
        exit 2
      fi

      if [ ! -w "$i" ]; then
        echo "E: $ME: unwriteable file: $i" >&2
        exit 3
      fi

      echo ": $i"
      vorbiscomment -l "$i"
      echo
      ;;

    *)
      echo "E: $ME: invalid argument: $i" >&2
      exit 1
      ;;
  esac
done >> $TMPFILE
echo : EOF >> $TMPFILE

MD5SUM=$(md5sum $TMPFILE)

[ -n "${DISPLAY:-}" ] && [ -n "${VISUAL:-}" ] && EDITOR="$VISUAL"
if [ -z "${EDITOR:-}" ]; then
  for i in sensible-editor editor vim emacs nano vi; do
    P="$(command -v $i)"
    [ -x "$P" ] && EDITOR="$P" && break
  done
fi

if [ -z "${EDITOR}" ]; then
  echo "E: $ME: no editor found." >&2
  exit 4
fi

eval $EDITOR $TMPFILE

if echo "$MD5SUM" | md5sum -c >/dev/null 2>&1; then
  echo "I: $ME: no changes, exiting..." >&2
  exit 0
fi

tags=''

echo "I: processing files..." >&2

write_tags() {
  local file="$1"; shift
  for tag; do echo "$tag"; done | vorbiscomment -w "$file"
}

while read line; do
  case "$line" in
    ': EOF')
      write_tags "$file" "$tags"
      echo "done." >&2
      ;;

    :*)
      if [ -n "${file:-}" ]; then
        write_tags "$file" "$tags"
        echo "done." >&2
        tags=''
      fi
      file="${line#: }"
      echo -n "I:   processing $file... " >&2
      ;;

    *=*)
      tags="${tags:+$tags\\n}$line";;

    *|'#*') :;;
  esac
done < $TMPFILE

echo "I: done." >&2

rm -f $TMPFILE
trap - 0

exit 0
