#!/usr/bin/env python3
# Copyright (c) Microsoft Corporation
# SPDX-License-Identifier: MIT
# Copied from 27e322f of https://github.com/microsoft/uf2/blob/master/utils/uf2conv.py
# pylint: skip-file
import argparse
import json
import os
import os.path
import re
import struct
import subprocess
import sys
from time import sleep

UF2_MAGIC_START0 = 0x0A324655  # "UF2\n"
UF2_MAGIC_START1 = 0x9E5D5157  # Randomly selected
UF2_MAGIC_END = 0x0AB16F30  # Ditto

INFO_FILE = "/INFO_UF2.TXT"

appstartaddr = 0x2000
familyid = 0x0


def is_uf2(buf):
    w = struct.unpack("<II", buf[0:8])
    return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1


def is_hex(buf):
    try:
        w = buf[0:30].decode("utf-8")
    except UnicodeDecodeError:
        return False
    return w[0] == ':' and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf)


def convert_from_uf2(buf):
    global appstartaddr
    global familyid
    numblocks = len(buf) // 512
    curraddr = None
    currfamilyid = None
    families_found = {}
    prev_flag = None
    all_flags_same = True
    outp = []
    for blockno in range(numblocks):
        ptr = blockno * 512
        block = buf[ptr : ptr + 512]
        hd = struct.unpack(b"<IIIIIIII", block[0:32])
        if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
            print("Skipping block at " + ptr + "; bad magic")
            continue
        if hd[2] & 1:
            # NO-flash flag set; skip block
            continue
        datalen = hd[4]
        if datalen > 476:
            raise AssertionError("Invalid UF2 data size at " + ptr)
        newaddr = hd[3]
        if (hd[2] & 0x2000) and (currfamilyid is None):
            currfamilyid = hd[7]
        if curraddr is None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
            currfamilyid = hd[7]
            curraddr = newaddr
            if familyid == 0x0 or familyid == hd[7]:
                appstartaddr = newaddr
        padding = newaddr - curraddr
        if padding < 0:
            raise AssertionError("Block out of order at " + ptr)
        if padding > 10 * 1024 * 1024:
            raise AssertionError("More than 10M of padding needed at " + ptr)
        if padding % 4 != 0:
            raise AssertionError("Non-word padding size at " + ptr)
        while padding > 0:
            padding -= 4
            outp.append(b"\x00\x00\x00\x00")
        if familyid == 0x0 or ((hd[2] & 0x2000) and familyid == hd[7]):
            outp.append(block[32 : 32 + datalen])
        curraddr = newaddr + datalen
        if hd[2] & 0x2000:
            if hd[7] in families_found:
                if families_found[hd[7]] > newaddr:
                    families_found[hd[7]] = newaddr
            else:
                families_found[hd[7]] = newaddr
        if prev_flag is None:
            prev_flag = hd[2]
        if prev_flag != hd[2]:
            all_flags_same = False
        if blockno == (numblocks - 1):
            print("--- UF2 File Header Info ---")
            families = load_families()
            for family_hex in families_found:
                family_short_name = ""
                for name, value in families.items():
                    if value == family_hex:
                        family_short_name = name
                print(f"Family ID is {family_short_name:s}, hex value is 0x{family_hex:08x}")
                print(f"Target Address is 0x{families_found[family_hex]:08x}")
            if all_flags_same:
                print(f"All block flag values consistent, 0x{hd[2]:04x}")
            else:
                print("Flags were not all the same")
            print("----------------------------")
            if len(families_found) > 1 and familyid == 0x0:
                outp = []
                appstartaddr = 0x0
    return b"".join(outp)


def convert_to_carray(file_content):
    outp = f"const unsigned long bindata_len = {len(file_content)};\n"
    outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
    for i in range(len(file_content)):
        if i % 16 == 0:
            outp += "\n"
        outp += f"0x{file_content[i]:02x}, "
    outp += "\n};\n"
    return bytes(outp, "utf-8")


def convert_to_uf2(file_content):
    global familyid
    datapadding = b""
    while len(datapadding) < 512 - 256 - 32 - 4:
        datapadding += b"\x00\x00\x00\x00"
    numblocks = (len(file_content) + 255) // 256
    outp = []
    for blockno in range(numblocks):
        ptr = 256 * blockno
        chunk = file_content[ptr : ptr + 256]
        flags = 0x0
        if familyid:
            flags |= 0x2000
        hd = struct.pack(
            b"<IIIIIIII",
            UF2_MAGIC_START0,
            UF2_MAGIC_START1,
            flags,
            ptr + appstartaddr,
            256,
            blockno,
            numblocks,
            familyid,
        )
        while len(chunk) < 256:
            chunk += b"\x00"
        block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
        assert len(block) == 512
        outp.append(block)
    return b"".join(outp)


class Block:
    def __init__(self, addr):
        self.addr = addr
        self.bytes = bytearray(256)

    def encode(self, blockno, numblocks):
        global familyid
        flags = 0x0
        if familyid:
            flags |= 0x2000
        hd = struct.pack(
            "<IIIIIIII",
            UF2_MAGIC_START0,
            UF2_MAGIC_START1,
            flags,
            self.addr,
            256,
            blockno,
            numblocks,
            familyid,
        )
        hd += self.bytes[0:256]
        while len(hd) < 512 - 4:
            hd += b"\x00"
        hd += struct.pack("<I", UF2_MAGIC_END)
        return hd


def convert_from_hex_to_uf2(buf):
    global appstartaddr
    appstartaddr = None
    upper = 0
    currblock = None
    blocks = []
    for line in buf.split('\n'):
        if line[0] != ":":
            continue
        i = 1
        rec = []
        while i < len(line) - 1:
            rec.append(int(line[i : i + 2], 16))
            i += 2
        tp = rec[3]
        if tp == 4:
            upper = ((rec[4] << 8) | rec[5]) << 16
        elif tp == 2:
            upper = ((rec[4] << 8) | rec[5]) << 4
        elif tp == 1:
            break
        elif tp == 0:
            addr = upper + ((rec[1] << 8) | rec[2])
            if appstartaddr is None:
                appstartaddr = addr
            i = 4
            while i < len(rec) - 1:
                if not currblock or currblock.addr & ~0xFF != addr & ~0xFF:
                    currblock = Block(addr & ~0xFF)
                    blocks.append(currblock)
                currblock.bytes[addr & 0xFF] = rec[i]
                addr += 1
                i += 1
    numblocks = len(blocks)
    resfile = b""
    for i in range(0, numblocks):
        resfile += blocks[i].encode(i, numblocks)
    return resfile


def to_str(b):
    return b.decode("utf-8")


def get_drives():
    drives = []
    if sys.platform == "win32":
        r = subprocess.check_output(
            [
                "wmic",
                "PATH",
                "Win32_LogicalDisk",
                "get",
                "DeviceID,",
                "VolumeName,",
                "FileSystem,",
                "DriveType",
            ]
        )
        for line in to_str(r).split('\n'):
            words = re.split(r'\s+', line)
            if len(words) >= 3 and words[1] == "2" and words[2] == "FAT":
                drives.append(words[0])
    else:
        searchpaths = ["/media"]
        if sys.platform == "darwin":
            searchpaths = ["/Volumes"]
        elif sys.platform == "linux":
            searchpaths += ["/media/" + os.environ["USER"], '/run/media/' + os.environ["USER"]]

        for rootpath in searchpaths:
            if os.path.isdir(rootpath):
                for d in os.listdir(rootpath):
                    if os.path.isdir(rootpath):
                        drives.append(os.path.join(rootpath, d))

    def has_info(d):
        try:
            return os.path.isfile(d + INFO_FILE)
        except Exception:
            return False

    return list(filter(has_info, drives))


def board_id(path):
    with open(path + INFO_FILE) as file:
        file_content = file.read()
    return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)


def list_drives():
    for d in get_drives():
        print(d, board_id(d))


def write_file(name, buf):
    with open(name, "wb") as f:
        f.write(buf)
    print(f"Wrote {len(buf)} bytes to {name}")


def load_families():
    # The expectation is that the `uf2families.json` file is in the same
    # directory as this script. Make a path that works using `__file__`
    # which contains the full path to this script.
    filename = "uf2families.json"
    pathname = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
    with open(pathname) as f:
        raw_families = json.load(f)

    families = {}
    for family in raw_families:
        families[family["short_name"]] = int(family["id"], 0)

    return families


def main():
    global appstartaddr, familyid

    def error(msg):
        print(msg, file=sys.stderr)
        sys.exit(1)

    parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
    parser.add_argument(
        'input', metavar='INPUT', type=str, nargs='?', help='input file (HEX, BIN or UF2)'
    )
    parser.add_argument(
        '-b',
        '--base',
        dest='base',
        type=str,
        default="0x2000",
        help='set base address of application for BIN format (default: 0x2000)',
    )
    parser.add_argument(
        '-f',
        '--family',
        dest='family',
        type=str,
        default="0x0",
        help='specify familyID - number or name (default: 0x0)',
    )
    parser.add_argument(
        '-o',
        '--output',
        metavar="FILE",
        dest='output',
        type=str,
        help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible',
    )
    parser.add_argument('-d', '--device', dest="device_path", help='select a device path to flash')
    parser.add_argument('-l', '--list', action='store_true', help='list connected devices')
    parser.add_argument('-c', '--convert', action='store_true', help='do not flash, just convert')
    parser.add_argument('-D', '--deploy', action='store_true', help='just flash, do not convert')
    parser.add_argument('-w', '--wait', action='store_true', help='wait for device to flash')
    parser.add_argument(
        '-C', '--carray', action='store_true', help='convert binary file to a C array, not UF2'
    )
    parser.add_argument(
        '-i',
        '--info',
        action='store_true',
        help='display header information from UF2, do not convert',
    )
    args = parser.parse_args()
    appstartaddr = int(args.base, 0)

    families = load_families()

    if args.family.upper() in families:
        familyid = families[args.family.upper()]
    else:
        try:
            familyid = int(args.family, 0)
        except ValueError:
            error("Family ID needs to be a number or one of: " + ", ".join(families.keys()))

    if args.list:
        list_drives()
    else:
        if not args.input:
            error("Need input file")
        with open(args.input, mode='rb') as f:
            inpbuf = f.read()
        from_uf2 = is_uf2(inpbuf)
        ext = "uf2"
        if args.deploy:
            outbuf = inpbuf
        elif from_uf2 and not args.info:
            outbuf = convert_from_uf2(inpbuf)
            ext = "bin"
        elif from_uf2 and args.info:
            outbuf = ""
            convert_from_uf2(inpbuf)
        elif is_hex(inpbuf):
            outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"))
        elif args.carray:
            outbuf = convert_to_carray(inpbuf)
            ext = "h"
        else:
            outbuf = convert_to_uf2(inpbuf)
        if not args.deploy and not args.info:
            print(
                f"Converted to {ext}, output size: {len(outbuf)}, start address: 0x{appstartaddr:x}"
            )
        if (args.convert or ext != "uf2") and args.output is None:
            args.output = "flash." + ext
        if args.output:
            write_file(args.output, outbuf)
        if ext == "uf2" and not args.convert and not args.info:
            drives = get_drives()
            if len(drives) == 0:
                if args.wait:
                    print("Waiting for drive to deploy...")
                    while len(drives) == 0:
                        sleep(0.1)
                        drives = get_drives()
                elif not args.output:
                    error("No drive to deploy.")
            for d in drives:
                print(f"Flashing {d:s} ({board_id(d):s})")
                write_file(d + "/NEW.UF2", outbuf)


if __name__ == "__main__":
    main()
