"""File-like objects that add timestamps to the input lines"""

from __future__ import absolute_import
from nilmdb.printf import *

import time
import os
import datetime_tz

class Timestamper(object):
    """A file-like object that adds timestamps to lines of an input file."""
    def __init__(self, file, ts_iter):
        """file: filename, or another file-like object
           ts_iter: iterator that returns a timestamp string for
           each line of the file"""
        if isinstance(file, basestring):
            self.file = open(file, "r")
        else:
            self.file = file
        self.ts_iter = ts_iter

    def close(self):
        self.file.close()

    def readline(self, *args):
        while True:
            line = self.file.readline(*args)
            if not line:
                return ""
            if line[0] == '#':
                continue
            break
        try:
            return self.ts_iter.next() + line
        except StopIteration:
            return ""

    def readlines(self, size = None):
        out = ""
        while True:
            line = self.readline()
            out += line
            if not line or (size and len(out) >= size):
                break
        return out

    def __iter__(self):
        return self

    def next(self):
        result = self.readline()
        if not result:
            raise StopIteration
        return result

class TimestamperRate(Timestamper):
    """Timestamper that uses a start time and a fixed rate"""
    def __init__(self, file, start, rate, end = None):
        """
        file: file name or object

        start: Unix timestamp for the first value

        rate: 1/rate is added to the timestamp for each line

        end: If specified, raise StopIteration before outputting a value
             greater than this."""
        def iterator(start, rate, end):
            n = 0
            rate = float(rate)
            while True:
                now = start + n / rate
                if end and now >= end:
                    raise StopIteration
                yield sprintf("%.6f ", start + n / rate)
                n += 1
        # Handle case where we're passed a datetime or datetime_tz object
        if "totimestamp" in dir(start):
            start = start.totimestamp()
        Timestamper.__init__(self, file, iterator(start, rate, end))
        self.start = start
        self.rate = rate
    def __str__(self):
        start = datetime_tz.datetime_tz.fromtimestamp(self.start)
        start = start.strftime("%a, %d %b %Y %H:%M:%S %Z")
        return sprintf("TimestamperRate(..., start=\"%s\", rate=%g)",
                       str(start), self.rate)

class TimestamperNow(Timestamper):
    """Timestamper that uses current time"""
    def __init__(self, file):
        def iterator():
            while True:
                now = datetime_tz.datetime_tz.utcnow().totimestamp()
                yield sprintf("%.6f ", now)
        Timestamper.__init__(self, file, iterator())
    def __str__(self):
        return "TimestamperNow(...)"

class TimestamperNull(Timestamper):
    """Timestamper that adds nothing to each line"""
    def __init__(self, file):
        def iterator():
            while True:
                yield ""
        Timestamper.__init__(self, file, iterator())
    def __str__(self):
        return "TimestamperNull(...)"
