from nilmdb.utils.printf import *
import nilmdb.client
import nilmdb.utils.timestamper as timestamper
import nilmdb.utils.time

import sys

def setup(self, sub):
    cmd = sub.add_parser("insert", help="Insert data",
                         description="""
                         Insert data into a stream.
                         """)
    cmd.set_defaults(verify = cmd_insert_verify,
                     handler = cmd_insert)
    cmd.add_argument("-q", "--quiet", action='store_true',
                     help='suppress unnecessary messages')

    group = cmd.add_argument_group("Timestamping",
                                   description="""
                                   To add timestamps, specify the
                                   arguments --timestamp and --rate,
                                   and provide a starting time.
                                   """)

    group.add_argument("-t", "--timestamp", action="store_true",
                       help="Add timestamps to each line")
    group.add_argument("-r", "--rate", type=float,
                       help="Data rate, in Hz",
                       ).completer = self.complete.rate

    group = cmd.add_argument_group("Start time",
                                   description="""
                                   Start time may be manually
                                   specified with --start, or guessed
                                   from the filenames using
                                   --filename.  Set the TZ environment
                                   variable to change the default
                                   timezone.""")

    exc = group.add_mutually_exclusive_group()
    exc.add_argument("-s", "--start",
                     metavar="TIME", type=self.arg_time,
                     help="Starting timestamp (free-form)",
                     ).completer = self.complete.time
    exc.add_argument("-f", "--filename", action="store_true",
                     help="Use filename to determine start time")

    group = cmd.add_argument_group("End time",
                                   description="""
                                   End time for the overall stream.
                                   (required when not using --timestamp).
                                   Set the TZ environment
                                   variable to change the default
                                   timezone.""")
    group.add_argument("-e", "--end",
                       metavar="TIME", type=self.arg_time,
                       help="Ending timestamp (free-form)",
                       ).completer = self.complete.time

    group = cmd.add_argument_group("Required parameters")
    group.add_argument("path",
                       help="Path of stream, e.g. /foo/bar",
                       ).completer = self.complete.path
    group.add_argument("file", nargs = '?', default='-',
                       help="File to insert (default: - (stdin))")
    return cmd

def cmd_insert_verify(self):
    if self.args.timestamp:
        if not self.args.rate:
            self.die("error: --rate is needed, but was not specified")
        if not self.args.filename and self.args.start is None:
            self.die("error: need --start or --filename when adding timestamps")
    else:
        if self.args.start is None or self.args.end is None:
            self.die("error: when not adding timestamps, --start and "
                     "--end are required")

def cmd_insert(self):
    # Find requested stream
    streams = self.client.stream_list(self.args.path)
    if len(streams) != 1:
        self.die("error getting stream info for path %s", self.args.path)

    arg = self.args

    try:
        filename = arg.file
        if filename == '-':
            infile = sys.stdin.buffer
        else:
            try:
                infile = open(filename, "rb")
            except IOError:
                self.die("error opening input file %s", filename)

        if arg.start is None:
            try:
                arg.start = nilmdb.utils.time.parse_time(filename)
            except ValueError:
                self.die("error extracting start time from filename '%s'",
                         filename)

        if arg.timestamp:
            data = timestamper.TimestamperRate(infile, arg.start, arg.rate)
        else:
            data = iter(lambda: infile.read(1048576), b'')

        # Print info
        if not arg.quiet:
            printf(" Input file: %s\n", filename)
            printf(" Start time: %s\n",
                   nilmdb.utils.time.timestamp_to_human(arg.start))
            if arg.end:
                printf("   End time: %s\n",
                       nilmdb.utils.time.timestamp_to_human(arg.end))
            if arg.timestamp:
                printf("Timestamper: %s\n", str(data))

        # Insert the data
        self.client.stream_insert(arg.path, data, arg.start, arg.end)

    except nilmdb.client.Error as e:
        # TODO: It would be nice to be able to offer better errors
        # here, particularly in the case of overlap, which just shows
        # ugly bracketed ranges of 16-digit numbers and a mangled URL.
        # Need to consider adding something like e.prettyprint()
        # that is smarter about the contents of the error.
        self.die("error inserting data: %s", str(e))

    return
