#!/usr/bin/env python
"""
Prints out the current time in UNIX timestamp.  It is sometimes useful to have a
valid UNIX timestamp in order to debug timing and timezone problems.

With a timestamp argument, convert the time in a human-readable date in the
current timezone.

See also: http://www.unixtimestamp.com
"""
__author__ = 'Martin Blais <blais@furius.ca>'

import argparse
import datetime
import functools
import logging
import re
import sys
import time

from dateutil import parser as duparser
from dateutil import tz


def convert_timestamp(min_timestamp, match):
    number = int(match.group())
    if min_timestamp is not None and number < min_timestamp:
        return match.group()
    else:
        return '"{}"'.format(datetime.datetime.fromtimestamp(number))

def process_input(out, arg_all=False):
    if arg_all:
        min_timestamp = None
    else:
        # A date two years before now.
        min_date = datetime.date.today() - datetime.timedelta(days=2*365)
        min_timestamp = time.mktime(min_date.timetuple())
    converter = functools.partial(convert_timestamp, min_timestamp)

    for line in sys.stdin:
        fline = re.sub(r'\b\d{9,10}\b', converter, line)
        out.write(fline)


verbose_fmt = '\t# %Y-%m-%d %H:%M:%S.%f %Z'

EPOCH = datetime.datetime(1970, 1, 1, tzinfo=tz.tzutc())


def main():
    parser = argparse.ArgumentParser(description=__doc__.strip())
    parser.add_argument('-v', '--verbose', action='store_true',
                        help="Output the human-readable date as a comment")

    parser.add_argument('-z', '--timezone', '--tz', action='store',
                        help="Timezone to use for times (default is local)")

    parser.add_argument('-Z', '--output-timezone', action='store',
                        help="Timezone for output (default is same as input)")

    parser.add_argument('times', nargs='*', action='store',
                        help="Times to be converted (default is now)")

    parser.add_argument('-i', '--input', action='store_true',
                        help="Process all timestampts in input from stdin")

    args = parser.parse_args()
    out = sys.stdout

    if args.input:
        process_input(out)
    else:
        # Input timezone (or use local).
        input_zone = tz.gettz(args.timezone) if args.timezone else tz.tzlocal()

        times = []
        if not args.times:
            times.append(datetime.datetime.now(input_zone))
        else:
            for arg in args.times:
                if re.match(r'\d+(\.\d*)?$', arg):
                    dt = datetime.datetime.fromtimestamp(int(arg), tz.tzutc())
                else:
                    dt = datetime.datetime.strptime(arg, r"%Y-%m-%d %H:%M:%S")
                    dt = dt.replace(tzinfo=input_zone)
                times.append(dt)

        # Output timezone
        output_zone = tz.gettz(args.output_timezone) if args.output_timezone else tz.tzlocal()

        for dt in times:
            ts = (dt - EPOCH).total_seconds()
            out.write(str(ts))
            if args.verbose:
                out.write(dt.astimezone(output_zone).strftime(verbose_fmt))
            out.write('\n')


if __name__ == '__main__':
    main()
