#!/usr/bin/env python3 -u
#
# This script reads from serial and prints the output
#

import argparse

import hmtl.portscan as portscan
from hmtl.SerialBuffer import SerialBuffer
from hmtl.SocketBuffer import SocketBuffer
from hmtl.StdinBuffer import StdinBuffer
from hmtl.TimedLogger import TimedLogger


def handle_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("-d", "--device", dest="device",
                        help="Arduino USB device")

    parser.add_argument("-b", "--baud", dest="baud", type=int,
                        help="Serial port baud ([9600], 19200, 57600, 115200)",
                        default=9600)
    
    parser.add_argument("-t", "--timestamp", dest="timestamp",
                        action="store_true",
                        help="Print timestamps", default=False)

    parser.add_argument("-i", "--input", dest="input",
                        action="store_true",
                        help="Resend stdin to the serial device", default=False)

    parser.add_argument("-I", "--ip", dest="ip",
                        help="Connect to the indicated IP address")
    parser.add_argument("-P", "--port", dest="port", type=int, default=23,
                        help="Port to connect to [default=%(default)s]")

    options = parser.parse_args()

    if options.device is None and options.ip is None:
        options.device = portscan.choose_port()

        if options.device is None:
            parser.print_help()
            exit("Must specify device")

    return options


def main():
    options = handle_args()

    if options.device is not None:
        device = SerialBuffer(options.device, options.baud, verbose=False)
    elif options.ip is not None:
        device = SocketBuffer(options.ip, options.port, verbose=False)
    else:
        exit("No device or address specified")

    stdin = StdinBuffer(verbose=False)

    device.start()
    stdin.start()

    logger = TimedLogger()
    while True:
        # Check the stdin buffer for data
        item = stdin.get(0)
        if item:
            data = item.data.strip()
            if options.input:
                # Resend the input over the serial connection
                logger.log("RESEND: %s" % data, color=TimedLogger.RED)
                device.write(data + "\n")
            else:
                logger.log("READ: %s" % data, color=TimedLogger.CYAN)

        # Check the serial queue for data
        item = device.get(0.1)
        if not item:
            continue

        data = item.data.strip()
        try:
            # Attempt to print the item as ascii
            text = str(data)
        except UnicodeDecodeError:
            # Failing that, print the raw data as hex
            text = ":".join("{:02x}".format(ord(c)) for c in data)

        if options.timestamp:
            logger.log(text)
        else:
            print(text)


if __name__ == '__main__':
    main()