#!/bin/bash
pname="$(basename "$0")"
device=/dev/disk1

# default implementation:

function eject(){
    read -p 'Please eject the CDROM, and type RET'
}

function wait_cd(){
    local cd="$1"
    printf "Waiting for the CD %s\n" "$cd"
    read -p "Please insert a CDROM, and type RET when it's ready"
}


# system specific override:

case "$(uname)" in
Darwin)
    function eject(){
        drutil eject
    }
    function wait_cd(){
        local cd="$1"
        local gotit=0
        while [ $gotit -eq 0 ] ; do
            if  df | grep -q -s "$device"  ; then
                gotit=1
            else
                printf "Waiting for the CD %s\n" "$cd"
                sleep 1
            fi
        done
    }
    ;;
Linux|linux)
    function eject(){
        command eject
    }
    ;;
esac


function cpcd(){
    local dir="$1"
    wait_cd "${dir}"
    mkdir -p "${dir}"
    ( cd "${dir}" ;\
      cd-info > cddb.txt ;\
      cdparanoia --query 2> cdparanoia.txt ;\
      cdparanoia --output-wav --batch ;\
      eject ;\
      printf "Compressing in background.\n" ;\
      for f in *.wav ; do \
          flac --silent -V --compression-level-8 "${f}" >> flac.log && rm "${f}" ;\
      done & )
}


function usage(){
    printf "%s usage:\n" "$pname"
    printf "   %s -h|--help\n" "$pname"
    printf "   %s -b|--batch \$start [-f|--directory-format \$format] [-d|--device \$device]\n" "$pname"
    printf "   %s \$directory\n" "$pname"
    printf "\nExamples:\n"
    printf "   %s one-CDA\n" "$pname"
    printf "   %s -b 1 -f 'cd%%02d-multiple-CDAs'\n" "$pname"
    printf "\n"
}


dir=''
start=''
format='cd%02d'

function parse_arguments(){
    local arg
    while [ $# -gt 0 ] ; do
        arg="$1" ; shift
        case "$arg" in
        -h|--help)
            usage
            exit 0
            ;;
        -d|--device)
            if [ $# -gt 0 ] ; then
                device="$1" ; shift
            else
                printf "Missing the device after %s\n" "$arg"
                usage
                exit 1
            fi
            ;;
        -b|--batch)
            if [ $# -gt 0 ] ; then
                start="$1" ; shift
            else
                printf "Missing the start index after %s\n" "$arg"
                usage
                exit 1
            fi
            ;;
        -f|--directory-format)
            if [ $# -gt 0 ] ; then
                format="$1" ; shift
            else
                printf "Missing the directory format string after %s\n" "$arg"
                usage
                exit 1
            fi
            ;;
        -*)
            printf "Invalid option: %s\n" "$arg"
            usage
            exit 1
            ;;
        *)
            if [ "$dir" = '' ] ; then
                dir="$arg"
            else
                printf "Too many arguments: %s\n" "$arg"
                usage
                exit 1
            fi
            ;;
        esac
    done

    if [ "$dir" = '' -a "$start" = '' ] ; then
        # shellcheck disable=SC2016
        printf 'Please give either -b $start or $directory.\n'
        usage
        exit 1
    fi

    if [ "$dir" != '' -a "$start" != '' ] ; then
        # shellcheck disable=SC2016
        printf '-b $start and $directory are mutually exclusive.\n'
        usage
        exit 1
    fi
}


function main(){
    parse_arguments "$@"
    if [ "$start" != '' ] ; then
        case "$start" in
        (*[^0-9]*)
            printf "Invalid start index, it must be an integer, not '%s'\n" "$start"
            usage
            exit 1
            ;;
        esac
        index=$start
        while true ; do
            # shellcheck disable=SC2059
            cpcd "$(printf "$format" "$index")"
            ((index++))
        done
    else
        cpcd "${dir}"
    fi
    exit 0
}


main "$@"
ViewGit