from nilmdb.utils.printf import *
import nilmdb.utils.time
from nilmdb.utils.interval import Interval

import fnmatch
import argparse
from argparse import ArgumentDefaultsHelpFormatter as def_form

def setup(self, sub):
    cmd = sub.add_parser("intervals", help="List intervals",
                         formatter_class = def_form,
                         description="""
                         List intervals in a stream, similar to
                         'list --detail path'.

                         If '--diff diffpath' is provided, only
                         interval ranges that are present in 'path'
                         and not present in 'diffpath' are printed.
                         """)
    cmd.set_defaults(verify = cmd_intervals_verify,
                     handler = cmd_intervals)

    group = cmd.add_argument_group("Stream selection")
    group.add_argument("path", metavar="PATH",
                       help="List intervals for this path",
                       ).completer = self.complete.path
    group.add_argument("-d", "--diff", metavar="PATH",
                       help="Subtract intervals from this path",
                       ).completer = self.complete.path

    group = cmd.add_argument_group("Interval details")
    group.add_argument("-s", "--start",
                       metavar="TIME", type=self.arg_time,
                       help="Starting timestamp for intervals "
                       "(free-form, inclusive)",
                       ).completer = self.complete.time
    group.add_argument("-e", "--end",
                       metavar="TIME", type=self.arg_time,
                       help="Ending timestamp for intervals "
                       "(free-form, noninclusive)",
                       ).completer = self.complete.time

    group = cmd.add_argument_group("Misc options")
    group.add_argument("-T", "--timestamp-raw", action="store_true",
                       help="Show raw timestamps when printing times")
    group.add_argument("-o", "--optimize", action="store_true",
                       help="Optimize (merge adjacent) intervals")

    return cmd

def cmd_intervals_verify(self):
    if self.args.start is not None and self.args.end is not None:
        if self.args.start >= self.args.end:
            self.parser.error("start must precede end")

def cmd_intervals(self):
    """List intervals in a stream"""
    if self.args.timestamp_raw:
        time_string = nilmdb.utils.time.timestamp_to_string
    else:
        time_string = nilmdb.utils.time.timestamp_to_human

    try:
        intervals = ( Interval(start, end) for (start, end) in
                      self.client.stream_intervals(self.args.path,
                                                   self.args.start,
                                                   self.args.end,
                                                   self.args.diff) )
        if self.args.optimize:
            intervals = nilmdb.utils.interval.optimize(intervals)
        for i in intervals:
            printf("[ %s -> %s ]\n", time_string(i.start), time_string(i.end))

    except nilmdb.client.ClientError as e:
        self.die("error listing intervals: %s", str(e))

