#!/bin/bash

ME=${0##*/}

MARGIN=$((15 * 60))  # 15 minutes

VERBOSE=

usage() {
    local ret=${1:-0}
    cat <<Usage
Usage: $ME [options]

Guess whether the hardware clock is set to utc or to localtime based
on comparing it with a properly configured and set system time.

Prints out: "utc", "localtime", "both", or "unknown".

Options: 
  -h, --help     Show this usage
  -v, --verbose  Show our work (in Unix seconds)
Usage

    exit $ret
}

main() {

    local SHIFT
    read_params "$@"
    shift $SHIFT

    [ $# -gt 0 ]     && fatal "Unexpected command line argument(s): $*"
    [ "$UID" -eq 0 ] || fatal "You must be root to run this script"

    local sys_time=$(date +%s)
    show_time sys_time $sys_time

    local flag hw_time diff both
    for flag in utc localtime; do
        hw_time=$(get_hw_time $flag)
        show_time "$flag hw" $hw_time

        diff=$(abs $((hw_time - sys_time)))
        show_time  "$flag diff" $diff
        
        [ "$diff" -lt "$MARGIN" ] || continue
        [ "$FOUND" ] && both=true
        : ${FOUND:=$flag}
    done

    if [ "$both" ]; then
        echo both
    elif [ "$FOUND" ]; then
        echo $FOUND
    else
        echo "unknown"
    fi
}

read_params() {
    # Most of this code is boiler-plate for parsing cmdline args
    SHIFT=0
    # These are the single-char options that can stack
    local short_stack="hv"

    local arg val

    # Loop through the cmdline args
    while [ $# -gt 0 -a -n "$1" -a -z "${1##-*}" ]; do
        arg=${1#-}
        shift
        SHIFT=$((SHIFT + 1))
        # Expand stacked single-char arguments
        case $arg in
            [$short_stack][$short_stack]*)
                if echo "$arg" | grep -q "^[$short_stack]\+$"; then
                    set -- $(echo $arg | sed -r 's/([a-zA-Z])/ -\1 /g') "$@"
                    continue
                fi;;
        esac

        # Deal with all options that take a parameter
        case $arg in

          # Add options to this list if the take a parameter
          -major-num|-min-size|[mM])
                [ $# -lt 1 ] && fatal "Expected a parameter after: -$arg"
                val=$1
                [ -n "$val" -a -z "${val##-*}" ] \
                    && fatal "Suspicious argument after -$arg: $val"
                    SHIFT=$((shift + 1))
                    shift             ;;

                  *=*)  val=${arg#*=} ;;
                    *)  val="???"     ;;
        esac

        # Edit this case statement when adding/removing options
        case $arg in
               -help|h) usage        ;;
            -verbose|v) VERBOSE=true ;;
                     *) fatal "Unknown parameter -$arg"
        esac
    done
}

get_hw_time() {
    flag=$1
    [ -n "$flag" ] && flag="--$flag"
    local hw_str=$(hwclock --show $flag | sed 's/  .*//')
    date +%s --date="$hw_str"
}

show_time() {
    [ -z "$VERBOSE" ] && return
    local label=$1 time=$2
    printf "%15s: %10s\n" "$label" "$time"
}

abs() { echo ${1#-}; }

fatal() {
    echo "$ME fatal error: $*"
    exit 2
}

main "$@"

