#!/bin/bash
##
## Mailman Hack: Archive search by Hyper Estraier: estcmd
## Copyright (c) 2008-2011 SATOH Fumiyasu @ OSS Technology, Inc.
##               <http://www.osstech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2011-05-30, since 2008-07-25
##

set -u
umask 0022

pinfo()
{
  echo "$0: INFO: $*"
}

perr()
{
  echo "$0: ERROR: $*" 1>&2
}

pdie()
{
  perr "$*"
  exit 1
}

bin_dir="${MM_BINDIR:-/opt/osstech/lib/mailman/bin}"
archive_dir="${MM_VARDIR:-/opt/osstech/var/lib/mailman}/archives"
private_dir="$archive_dir/private"
public_dir="$archive_dir/public"

## FIXME: Virtual domain support
private_archive_uri="${MM_PRIVATE_ARCHIVE_URI:-/mailman/private}"
public_archive_uri="${MM_PUBLIC_ARCHIVE_URI:-/pipermail}"

est_bin_dir="${ESTRAIER_BINDIR:-/opt/osstech/bin}"
est_cgibin_dir="${ESTRAIER_CGIBINDIR:-/opt/osstech/libexec/hyperestraier}"
est_data_dir="${ESTRAIER_DATADIR:-/opt/osstech/share/hyperestraier}"
est_locale="${ESTRAIER_LOCALE:-ja}"

num_dirs="2"

## FIXME: Add descriptions about command-line options and arguments
cmd_usage="Usage: $0 [OPTIONS] [LIST ...]"

## ----------------------------------------------------------------------

getopts_want_arg()
{
  if [ $# -lt 2 ]; then
    pdie "Option requires an argument: $1"
  fi
  if [ $# -ge 3 ]; then
    if expr x"$2" : x"$3\$" >/dev/null; then
      : OK
    else
      pdie "Invalid value for option: $1 $2"
    fi
  fi
}

while test "$#" -gt 0; do
  OPT="$1"; shift
  case "$OPT" in
  -a|--all-lists)
    ## Get all list names
    list_names=$("$bin_dir/list_lists" --bare) \
      || pdie "Cannot get list names"
    set -- ${1+"$@"} $list_names
    ;;
  -n)
    getopts_want_arg "$OPT" ${1+"$1"} ${1+"[0-9][0-9]*"}
    num_dirs="$1"; shift
    ;;
  --)
    break
    ;;
  -*)
    pdie "Invalid option: $OPT"
    exit 1
    ;;
  *)
    set -- "$OPT" ${1+"$@"}
    break
    ;;
  esac
done

if [ $# -lt 1 ]; then
  echo "$cmd_usage"
  exit 0
fi

if [ "$num_dirs" -eq 0 ]; then
  dirs_filter="cat"
else
  dirs_filter="tail -$num_dirs"
fi

## ======================================================================

private_dir_p=$(cd "$private_dir" && pwd -P) \
  || pdie "Cannot resolve Mailman private directory"

for list_name in "$@"; do
  list_archive_f=$(
    "$bin_dir/config_list" --outputfile - "$list_name" \
    |sed -n 's/^archive *= *\(.*\)$/\1/p'
  )
  case "$list_archive_f" in
  True|1)
    : OK
    ;;
  *)
    continue
    ;;
  esac

  pinfo "$list_name: Start."

  cd "$private_dir/$list_name" || {
    perr "$list_name: Cannot change working directory"
    continue
  }

  if [ ! -d "estraier" ]; then
    pinfo "$list_name: Creating index database ..."
    (
      set -e

      list_realname=$(
	"$bin_dir/config_list" --outputfile - "$list_name" \
	|sed -n 's/^real_name *= *.\(.*\).$/\1/p'
      )
      [ -n "$list_realname" ] || exit 1

      if [ -d "$public_dir/$list_name" ]; then
	## Public list
	archive_uri="$public_archive_uri"
      else
	## Private list
	archive_uri="$private_archive_uri"
      fi

      mkdir estraier estraier/db
      ln -s "$est_cgibin_dir/estseek.cgi" estraier/
      cp -p "$est_data_dir${est_locale:+/locale/$est_locale}"/estseek.* estraier/
      ln -s estseek.conf "estraier/$list_name.conf"
      cp -p estraier/estseek.conf estraier/estseek.conf.dist
      sed \
	-e 's/^\(indexname:\) .*/\1 db/' \
	-e 's/^\(deftitle:\) .*/\1 Search - Hyper Estraier/' \
	-e 's!^\(replace: \^file://\).*$!\1'"$private_dir_p/"'{{\!}}'"$archive_uri"'/!' \
        <estraier/estseek.conf.dist \
        >estraier/estseek.conf
      cp -p estraier/estseek.tmpl estraier/estseek.tmpl.dist
      sed \
	-e 's/\(<title>\)/\1'"$list_realname"' /' \
        <estraier/estseek.tmpl.dist \
        >estraier/estseek.tmpl
    )
    if [ $? -ne 0 ]; then
      perr "$list_name: Cannot create index database"
      rm -rf estraier
      continue
    fi
  fi

  pinfo "$list_name: Updating index database ..."

  ls -trF \
  |sed -n 's|^\(.*\)\.txt$|\1|p' \
  |$dirs_filter \
  |while read -r target_dir; do
    [ -d "$target_dir" ] || continue
    find "$target_dir" -name "[0-9]*.html" \
    |"$est_bin_dir/estcmd" \
      gather \
      ${est_lang:+-il "$est_lang"} \
      -cl \
      -cm \
      -sd \
      -fx "*" "H@${0%/*}/estfxhtmltohtml" \
      estraier/db \
      -
  done
  pinfo "$list_name: Done."
done

