#!/bin/bash
# (requires bash regexes)
# Converts default irssi autolog files from $tag/$0.log to $tag/$0/%Y-%m-%d.log.xz
# Note that you need to
#  /set autolog_path ~/irclogs/$tag/$0/%Y-%m-%d.log
#  /set autolog off
#  /set autolog on
# *before* running this, otherwise data loss is likely.
# Original log files are not deleted, and new log files are not overwritten
# (however, converted $tag/$0/%Y-%m-%d.log.xz and newly written $tag/$0/%Y-%m-%d.log will need to be merged outside the scope of this script.)
#
# assumptions:
#autolog_path ~/irclogs/$tag/$0/%Y-%m-%d.log
#log_close_string --- Log closed %a %b %d %H:%M:%S %Y
#log_create_mode 600
#log_day_changed --- Day changed %a %b %d %Y
#log_open_string --- Log opened %a %b %d %H:%M:%S %Y

set -e
set -x

umask 0077

log_open_regex="^--- Log opened ([a-zA-Z]{3} [a-zA-Z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4})$"
log_changed_regex="^--- Day changed ([a-zA-Z]{3} [a-zA-Z]{3} [0-9]{2} [0-9]{4})$"
log_close_regex="^--- Log closed ([a-zA-Z]{3} [a-zA-Z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} [0-9]{4})$"

cd ~/irclogs/

exists () {
# ! test -s "$1"        || ! echo nonempty null-date log detected       || exit
  ! test -s "$1".tmp    || ! echo "$1".tmp    nonempty file detected || exit
  ! test -s "$1".tmp.xz || ! echo "$1".tmp.xz nonempty file detected || exit
  ! test -s "$1".xz     || ! echo "$!".xz     nonempty file detected || exit
}

compress () {
  if [ -s "$1".tmp ] && grep -qv '^---' "$1".tmp; then
    xz "$1".tmp
    mv -i "$1".tmp.xz "$1".xz
  else
    rm "$1".tmp
  fi
}

for tag in [a-zA-Z]*; do
  if ! test -d $tag; then
    echo $tag is not a directory, ignoring...
    continue
  fi
  (
    cd $tag
    for oldlog in *.log; do
      test -f "$oldlog" || ! echo $oldlog is not a file, ignoring... || continue
      test -s "$oldlog" || ! echo $oldlog is empty, ignoring...      || continue
      chan="$( basename "$oldlog" .log )"

      mkdir -p "$chan"

      datestring=0000-00-00
      exists "$chan"/$datestring.log
      exec 9<>"$chan"/$datestring.log.tmp # open handle
      IFS=$'\n'
      ( # $oldlog is stdio'd into this subshell down below
        while read -r line; do
          if [[ "$line" =~ $log_open_regex ]] || [[ "$line" =~ $log_changed_regex ]]; then
            newdatestring=$( date --date="${BASH_REMATCH[1]}" +%Y-%m-%d )
            if [ "$newdatestring" != "$datestring" ]; then 
              exec 9<&- # close handle
              compress "$chan"/"$datestring".log
              datestring="$newdatestring"
              exists "$chan"/"$datestring".log
              exec 9<> "$chan"/"$datestring".log.tmp # open handle
            fi
  #       elif [[ "$line" =~ $log_close_regex ]]; then
          fi
          printf '%s\n' "$line" >&9 # write to handle to avoid reopens
        done
        exec 9<&- # close handle
        compress "$chan"/"$datestring".log
      ) < "$oldlog"
    done
  )
done
