#!/usr/bin/python

import time
import argparse
import os.path
import sys

from mpy_utils.replcontrol import ReplControl, ReplIOFileHandle, ReplIOSerial

parser = argparse.ArgumentParser(
    description="upload files to a device using only the REPL"
)
parser.add_argument("--port", default="/dev/ttyUSB0", help="serial port device")
parser.add_argument("--baud", default=115200, type=int, help="port speed in baud")
parser.add_argument(
    "--pipe", action="store_true", help="use stdin/stdout instead of serial port"
)
parser.add_argument(
    "--delay", default=100.0, type=float, help="delay between lines (ms)"
)
parser.add_argument(
    "--reset", action="store_true", help="send soft reset (control-D) after upload"
)
parser.add_argument(
    "--debug", default=False, action="store_true", help="print debugging info"
)
parser.add_argument("files", nargs="*", type=str)
args = parser.parse_args()

if args.pipe:
    repl_io = ReplIOFileHandle(infh=sys.stdin, outfh=sys.stdout)
else:
    repl_io = ReplIOSerial(port=args.port, baud=args.baud, delay=args.delay)

repl_control = ReplControl(
    io=repl_io, delay=args.delay, debug=args.debug, reset=args.reset,
)

repl_control.command("import os")


def sync_files(files):
    for source, dest in files:
        if os.path.isdir(source):
            repl_control.statement("os.mkdir", dest)
            sync_files(
                [
                    (os.path.join(source, x), os.path.join(dest, x))
                    for x in os.listdir(source)
                    if not x.startswith(".")
                ]
            )
        else:
            copy_file(source, dest)


def copy_file(source, dest):
    print("copying %s => %s" % (repr(source), repr(dest)), file=sys.stderr)
    fh = open(source, "rb")
    rfh = repl_control.variable("open", "/" + dest, "wb")
    while True:
        s = fh.read(50)
        if len(s) == 0:
            break
        rfh.method("write", s)
        time.sleep(args.delay / 1000.0)
    rfh.method("flush")
    rfh.method("close")


sync_files([(f, os.path.split(f)[1]) for f in args.files] or [(".", "/")])
