#!/bin/sh
#
# Render a temporalCoverage (ISO 8601 datetime or datetime range) on stdout
# in a format directly suitable to inject into an HTML5 document.
#
# This will also wrap in appropriate schema.org itemprop efficiently.
#
# Precision may be reduced to whole-day granularity for display.
#
# Usage: datetime/range [sourcename]
# 
#     $1 ISO 8601 datetime / range, UTC and HTML5 friendly if possible.
#     $2 optional source name for errors
#
# An empty $1 silently and without error returns nothing.
#
# Examples of acceptable values:
#     2009
#     2009-10
#     2009-10-01
#     2009-10-01T10:20Z
#     2009-10-01T10:20Z/..
#     2009-10-01T10:20:13Z/2009-11-01T10:20:50Z
#     2009-10-01T10:20:13Z/2009-11-01T10:20:50.298Z
#
# Formats not yet used in EOU need not be handled elegantly, eg "../2009",
# and can fall through to be rendered in the default textual format.
#
# Restrictions:
#     * A full year must be supplied (not just a century).
#     * All (optional) separators have to be used, eg '-' and ':'.
#     * No leading elements can be missing.
#     * All times must be preceded with 'T'.
#     * All times must be precise to at least minutes, ie not just hours.
#     * All times must be in UTC, ie suffixed with 'Z'.
#
# The last time component can have a decimal component.
#
# As a fallback, if this cannot interpret the value, it is rendered as-is,
# with a simple textual intro, and a WARNING is emitted on stderr.

tc="$1"
# Silently return nothing if no argument given.
if [ "" = "$tc" ]; then exit 0; fi

src="$2"

# Stop attempting to parse as soon as INVALID becomes true.
INVALID=false

# Number of parts: 1 for datetime point, 2 for range.
NPARTS="`echo $tc | awk -F/ '{print NF}'`"
if [ "$NPARTS" -lt 1 -o "$NPARTS" -gt 2 ]; then
    INVALID=true
    echo "WARNING: $src wrong number of parts ($NPARTS) in temporal coverage: '$tc'" 1>&2
fi

# FROM is point and/or start of range.
# RANGETO is end of range or empty if coverage is a point.
PFROM=""
RANGETO=""
if [ "false" = "$INVALID" ]; then
    # Extract the parts.
    PFROM="`echo $tc | awk -F/ '{print $1}'`"
    RANGETO="`echo $tc | awk -F/ '{print $2}'`"
    # Validate syntax of each part.
    for dt in $PFROM $RANGETO;
        do
        # Allow .. form for range end if two parts present.
        if [ 2 = $NPARTS -a ".." = "$dt" ]; then continue; fi
        # Return non-empty value if parse attempt succeeds.
        PARSEATTEMPT="`echo $dt | awk '
            /^[12][0-9][0-9][0-9](-[01][0-9](-[0-3][0-9](T[0-2][0-9]:[0-5][0-9](:[0-6][0-9])?([.][0-9]+)?Z)?)?)?$/
            '`"
        if [ "" = "$PARSEATTEMPT" ]; then
            INVALID=true
            echo "WARNING: $src cannot parse part '$dt' in temporal coverage: '$tc'" 1>&2
            # Don't break: allow generation of error for other part if needed.
            fi
        done

    # It is not legitimate to have a 'point' which is just ".."/
    if [ ".." = "$PFROM" -a "" = "$RANGETO" ]; then
        INVALID=true
        echo "WARNING: $src cannot have .. point temporal coverage: '$tc'" 1>&2
    fi
fi

# TODO: validate that the parts are correctly ordered if neither is "..".


if [ "false" = "$INVALID" ]; then
    # Valid range, so attempt to render in text for a human reader.
    # Use span for a point, else
    # use a meta element to inject machine-readable version when not a point,
    if [ "" = "$RANGETO" ]; then
        # Point.
        printf "temporal coverage <span itemprop=temporalCoverage>%s</span>" "$tc"
    else
        # Range.
        printf "temporal coverage <meta itemprop=temporalCoverage content=%s>" "$tc"
        if [ ".." = "$PFROM" -a ".." = "$RANGETO" ]; then
            printf "open"
        elif [ ".." = "$PFROM" ]; then
            printf "until %s" "$RANGETO"
        elif [ ".." = "$RANGETO" ]; then
            printf "%s onwards" "$PFROM"
        else
            printf "%s to %s" "$PFROM" "$RANGETO"
        fi
    fi
    # Done!
    exit 0
fi



echo "WARNING: $src unable to parse full temporal coverage: '$tc'" 1>&2
printf "temporal coverage <span itemprop=temporalCoverage>%s</span>" "$tc"

exit 1
