#!/bin/bash

set -o nounset

append=false
background=false
dated=false
pager=false
quiet=false

usage() {
    cat - <<EOF
    Usage: ${0##*/} [options] [--] <program> <arguments>

    Options:
        -a            -- Append to logfile instead of overwriting
        -b            -- Background process
        -d            -- Put date in logfile name
        -f <filename> -- Write to <filename> instead of default
        -h            -- This help message
        -l|p          -- Pipe logfile through pager (less) (implies -b, -q)
        -q            -- Quiet

EOF
}
while getopts ':abdf:hlpq' opt
do
    case $opt in
        (a) append=true ;;
        (b) background=true ;;
        (d) dated=true ;;
        (f) LOG_DIR=$(dirname "$OPTARG") ; LOG_NAME=$(basename "$OPTARG") ;;
        (h) usage ; exit 0 ;;
      (l|p) pager=true ; quiet=true ; background=true ;;
        (q) quiet=true ;;
        (*) echo Bad option; usage; exit 2 ;;
    esac
done

shift $(($OPTIND - 1))

if (($# < 1)); then
    echo "Need program name"
    usage
    exit 2
fi

true ${LOG_DIR:=.}
true ${LOG_NAME:=$(basename "$1").log}
if $dated; then
    LOG_NAME=${LOG_NAME%.log}-$(date +%m%d-%H%M).log
fi

if [[ ! -w $LOG_DIR ]]; then
    echo "$LOG_DIR not writable" >&2
    if [[ -d $HOME/log && -w $HOME/log ]]; then
        LOG_DIR=$HOME/log
    else
        LOG_DIR=$HOME
    fi
fi

LOG_FILE=$LOG_DIR/$LOG_NAME

$append || > "$LOG_FILE"

msg() { $quiet || echo "$@" >&4; }

exec 4>&2 3>&1 >> "$LOG_FILE" 2>&1

msg "start '$@' log to $LOG_FILE"
echo `date '+%Y.%m.%d %H:%M:%S'` `id -un`@`hostname`:`pwd` -- "$@"
if $background; then
    (
        # We don't want the backgrounded process catching a ^C meant for the
        # pager
        trap "" INT
        nohup "$@"
        err=$?
        echo `date '+%Y.%m.%d %H:%M:%S'` exit: $err
        msg "exit  '$@' err $err"
    ) &
    $pager && ${PAGER:-less -f} "$LOG_FILE" 1>&3 2>&4
    exit 0
else
    "$@"
    err=$?
    echo `date '+%Y.%m.%d %H:%M:%S'` exit: $err
    msg "exit  '$@' err $err"
    exit $err
fi

