#!/usr/bin/env bash
# packaging, library.org
# configuration, /home/swflint/Projects/library/library.org
export LIBRARY_FILE=${LIBRARY_FILE:-~/.library/library.rec}
export LIBRARY_DIRECTORY=${LIBRARY_DIRECTOR:-~/.library}
export LIBRARY_GIT=${LIBRARY_GIT:-detect}
export LIBRARY_DEFAULT_FIELDS=${LIBRARY_DEFAULT_FIELDS:-ID,Title,Author,LCCN,Location,Course}
# configuration ends here

# help-message, /home/swflint/Projects/library/library.org
if [[ $# -eq 0 ]] ; then
    echo "library [ help | query | add | git | bulk-add | report | edit | edit-matching | loan | return-book | withdraw | drop-withdrawn | init ]"
    exit
fi

function display_help {
    cat <<EOF
library [ help | query | add | git | bulk-add | report | edit | edit-matching | loan | return-book | init ]

help:       Display this help message.
query:      Query Library Database.
add:        Add a singular book record.
git:        Run a git command.
bulk-add:   Add a specified number of records.
report:     Run a report.
edit:       Edit the value of a specified field in a specified record.
edit-matching: Edit records matching a give expression
loan:       Loan a book out.
return-book:Process a book return
withdraw:   Withdraw a specified book
drop-withdrawn: Drop withdrawn books
init:       Initialize the database.
EOF
}
# help-message ends here

# handle-reports, /home/swflint/Projects/library/library.org
function do_report {
    if [[ $# -lt 1 ]] ; then
        echo "library report name args*"
        exit 1
    fi
    NAME=$1
    shift
    case "${NAME}" in
        list)
            for report in ${LIBRARY_DIRECTORY}/reports/*.report ;
            do
                echo " - $(basename -- "${report}" .report)"
            done
        ;;
        new)
            if [[ $# -lt 1 ]] ; then
                echo "library report new name"
                exit 1
            fi
            REPORT=$1
            shift
            echo "# -*- mode: shell-script -*-" > "${LIBRARY_DIRECTORY}/reports/${REPORT}.report"
            emacsclient --alternate-editor="" -n "${LIBRARY_DIRECTORY}/reports/${REPORT}.report"
        ;;
        *)
            if [[ -e "${LIBRARY_DIRECTORY}/reports/${NAME}.report" ]] ; then
               sh "${LIBRARY_DIRECTORY}/reports/${NAME}.report" "$@"
            fi
    esac
}
# handle-reports ends here

# handle-git, /home/swflint/Projects/library/library.org
function do_git {
    if [[ $# -lt 1 ]] ; then
        echo "library git args*"
        exit 1
    fi
    FIRST=$1
    if [[ $FIRST == "init" ]] ; then
        OLD=`pwd`
        cd "${LIBRARY_DIRECTORY}"
        git "$@"
        cd ${OLD}
    else
        if [[ $LIBRARY_GIT == "detect" ]] ; then
            OLD=`pwd`
            cd "${LIBRARY_DIRECTORY}"
            git "$@"
            cd ${OLD}
        fi
    fi
}
# handle-git ends here

# handle-query, /home/swflint/Projects/library/library.org
function run_query {
    recsel -t Book "$@" "${LIBRARY_FILE}"
}
# handle-query ends here

# add-book, /home/swflint/Projects/library/library.org
function add_single {
    if [[ $# -lt 7 ]] ; then
        read -e -p "Title: " TITLE
        read -e -p "Author: " AUTHOR
        read -e -p "LCCN: " LCCN
        read -e -p "Copyright Year: " COPYRIGHT
        read -e -p "Publisher: " PUBLISHER
        read -e -p "ISBN: " ISBN
        read -e -p "Location: " LOCATION
    else
        TITLE=$1
        shift
        AUTHOR=$1
        shift
        LCCN=$1
        shift
        COPYRIGHT=$1
        shift
        PUBLISHER=$1
        shift
        ISBN=$1
        shift
        LOCATION=$1
        shift
    fi
    TMPDIR=. recins -t Book \
           -f Title -v "${TITLE}" \
           -f Author -v "${AUTHOR}" \
           -f LCCN -v "${LCCN}" \
           -f Copyright -v "${COPYRIGHT}" \
           -f Publisher -v "${PUBLISHER}" \
           -f ISBN -v "${ISBN}" \
           -f Location -v "${LOCATION}" \
           -f Card -v UNPRINTED \
           "${LIBRARY_FILE}"
    do_git add `basename "${LIBRARY_FILE}"`
    do_git commit -m "Added record for \"${TITLE}\""
    library query -i --uniq -e "Title ~ \"${TITLE}\"" | less
}
# add-book ends here

# add-in-bulk, /home/swflint/Projects/library/library.org
function bulk_add {
    if [[ $@ -lt 1 ]] ; then
        echo "library bulk-add number"
        exit 1
    fi
    GITOLD="${LIBRARY_GIT}"
    LIBRARY_GIT=FALSE
    for i in 1 .. $1 ; do
        echo "Adding book number ${i}"
        add_single
    done
    LIBRARY_GIT="${GITOLD}"
    do_git add `basename "${LIBRARY_FILE}"`
    do_git commit -m "Added ${1} records"
}
# add-in-bulk ends here

# edit-field, /home/swflint/Projects/library/library.org
function do_edit {
    if [[ $# -lt 2 ]] ; then
        echo "library edit id field [ value ]"
        exit 1
    fi
    ID=$1
    shift
    FIELD=$1
    shift
    VALUE=$1
    shift
  
    TMPDIR=. recset -e "ID = ${ID}" \
          -f "${FIELD}" -S "${VALUE}" \
          "${LIBRARY_FILE}"

    do_git add `basename "${LIBRARY_FILE}"`
    do_git commit -m "Edited record id ${ID}"
}

function do_edit_exp {
    if [[ $# -lt 3 ]] ; then
        echo "library edit-matching match-exp field value [ commit-message  ]"
        exit 1
    fi
    MATCHEXPRESSION=$1
    shift
    FIELDNAME=$1
    shift
    VALUE=$1
    shift
    TMPDIR=. recset -e "${MATCHEXPRESSION}" \
          -f "${FIELDNAME}" -S "${VALUE}" \
          "${LIBRARY_FILE}"
    do_git add $(basename "${LIBRARY_FILE}")
    if [[ $1 != "" ]] ; then
        do_git commit -m "${1}"
    else
        do_git commit -m "Bulk edited records"
    fi
}
# edit-field ends here

# withdraw-books, /home/swflint/Projects/library/library.org
function do_withdraw {
    if [ $# -lt 1 ] ; then
        echo "library withdraw id"
        exit 1
    fi
    ID=$1
    TMPDIR=. recset -e "ID = ${ID}" \
          -f "Withdrawn" -S "`date +"%a, %d %b %Y %H:%M:%S %z"`" \
          -f "Location" -S "WITHDRAWN" \
          "${LIBRARY_FILE}"
    do_git add $(basename ${LIBRARY_FILE})
    do_git commit -m "Withdrew book ${ID}"
}

function remove_withdrawn {
    TMPDIR=. recdel -t Book \
          -e "Location ~ \"WITHDRAWN\"" \
          "${LIBRARY_FILE}"
    do_git add $(basename ${LIBRARY_FILE})
    do_git commit -m "Remove Withdrawn Books"
}
# withdraw-books ends here

# initialize-database, /home/swflint/Projects/library/library.org
function initialize {
    OLD=`pwd`
    mkdir -p "${LIBRARY_DIRECTORY}"
    cd "${LIBRARY_DIRECTORY}"
    [[ ! -e `basename "${LIBRARY_FILE}"` ]] && \
        cat <<EOF > `basename "${LIBRARY_FILE}"`
# file-format, /home/swflint/Projects/library/library.org
# -*- mode: rec -*-

%rec: Book
%doc: Foo
%key: ID
%unique: Title
%type: ID int
%type: Title line
%type: Author line
%type: LCCN line
%type: ISBN regexp /[0-9]*X?/
%type: Publisher line
%type: Copyright int
%type: Location line
%type: Withdrawn date
%type: Inserted date
%type: Course line
%type: LoanTo line
%type: LoanOn date
%typedef: CardPrint enum PRINTED REPRINT UNPRINTED
%type: Card CardPrint
%mandatory: Title Author LCCN Inserted
%allowed: ISBN Publisher Copyright Location Withdrawn LoanTo LoanOn Course Card
%auto: ID Inserted
# file-format ends here
EOF
}
# initialize-database ends here

# loan, /home/swflint/Projects/library/library.org
function do_loan {
    if [[ $# -lt 2 ]] ; then
        echo "library loan id name"
        exit 1
    fi

    ID=$1
    shift
    NAME=$1
    shift

    TMPDIR=. recset -e "ID = ${ID}" \
           -f "LoanTo" -S "${NAME}" \
           "${LIBRARY_FILE}"
    TMPDIR=. recset -e "ID = ${ID}" \
           -f "LoanOn" -S "`date +"%a, %d %b %Y %H:%M:%S %z"`" \
           "${LIBRARY_FILE}"
    do_git add `basename "${LIBRARY_FILE}"`
    do_git commit -m "Loaned Book ${ID} to ${NAME}"
}

function do_return {
    if [[ $# -lt 1 ]] ; then
        echo "library return-book id"
        exit 1
    fi

    ID=$1
    shift

    TMPDIR=. recset -e "ID = ${ID}" \
           -f "LoanTo" -d \
           "${LIBRARY_FILE}"
    TMPDIR=. recset -e "ID = ${ID}" \
           -f "LoanOn" -d \
           "${LIBRARY_FILE}"

    do_git add `basename "${LIBRARY_FILE}"`
    do_git commit -m "Returned Book ${ID}"
}
# loan ends here

# process-commands, /home/swflint/Projects/library/library.org
COMMAND=$1
shift

case "${COMMAND}" in
    help)
        display_help
        exit
        ;;
    query)
        run_query "$@"
        exit
        ;;
    add)
        add_single "$@"
        exit
        ;;
    git)
        do_git "$@"
        exit
        ;;
    bulk-add)
        bulk_add "$@"
        exit
        ;;
    report)
        do_report "$@"
        exit
        ;;
    edit)
        do_edit "$@"
        exit
        ;;
    edit-matching)
        do_edit_exp "$@"
        exit
        ;;
    loan)
         do_loan "$@"
         exit
         ;;
    return-book)
        do_return "$@"
        exit
        ;;
    withdraw)
        do_withdraw "$@"
        exit
        ;;
    drop-withdrawn)
        remove_withdrawn "$@"
        exit
        ;;
    init)
        initialize
        exit
        ;;
    *)
        display_help
        exit
esac
# process-commands ends here
# packaging ends here
