#!/usr/bin/env python
"""Generates the pins file for the SAMD port."""

from __future__ import print_function

import argparse
import sys
import csv

pins_header_prefix = """// This file was automatically generated by make-pins.py
//
typedef struct _machine_pin_obj_t {
    mp_obj_base_t base;
    uint32_t id;
    char *name;
} machine_pin_obj_t;

int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size);

"""

led_header_prefix = """typedef struct _machine_led_obj_t {
    mp_obj_base_t base;
    uint32_t id;
    char *name;
} machine_led_obj_t;

"""


class Pins:
    def __init__(self):
        self.board_pins = []  # list of pin objects
        self.board_leds = []  # list of led objects

    def parse_csv_file(self, filename):
        with open(filename, "r") as csvfile:
            rows = csv.reader(csvfile, skipinitialspace=True)
            for row in rows:
                # Pin numbers must start with "PIN_"
                # LED numbers must start with "LED_"
                if len(row) > 0:
                    if row[0].startswith("PIN_"):
                        if len(row) == 1:
                            self.board_pins.append([row[0], row[0][4:]])
                        else:
                            self.board_pins.append([row[0], row[1]])
                    elif row[0].startswith("LED_"):
                        self.board_leds.append(["PIN_" + row[0][4:], row[1]])
                    elif row[0].startswith("-"):
                        self.board_pins.append(["-1", ""])

    def print_pins(self, pins_filename):
        with open(pins_filename, "wt") as pins_file:
            pins_file.write("// This file was automatically generated by make-pins.py\n")
            pins_file.write("//\n")
            pins_file.write('#include "modmachine.h"\n')
            pins_file.write('#include "sam.h"\n')
            pins_file.write('#include "pins.h"\n\n')

            pins_file.write("const machine_pin_obj_t machine_pin_obj[] = {\n")
            for pin in self.board_pins:
                pins_file.write("    {{&machine_pin_type}, ")
                pins_file.write(pin[0] + ', "' + pin[1])
                pins_file.write('"},\n')
            pins_file.write("};\n")

            if self.board_leds:
                pins_file.write("\nconst machine_led_obj_t machine_led_obj[] = {\n")
                for pin in self.board_leds:
                    pins_file.write("    {{&machine_led_type}, ")
                    pins_file.write(pin[0] + ', "' + pin[1])
                    pins_file.write('"},\n')
                pins_file.write("};\n")

    def print_header(self, hdr_filename):
        with open(hdr_filename, "wt") as hdr_file:
            hdr_file.write(pins_header_prefix)
            if self.board_leds:
                hdr_file.write(led_header_prefix)
            hdr_file.write(
                "extern const machine_pin_obj_t machine_pin_obj[%d];\n" % len(self.board_pins)
            )
            if self.board_leds:
                hdr_file.write(
                    "extern const machine_led_obj_t machine_led_obj[%d];\n" % len(self.board_leds)
                )


def main():
    parser = argparse.ArgumentParser(
        prog="make-pins.py",
        usage="%(prog)s [options] [command]",
        description="Generate board specific pin file",
    )
    parser.add_argument(
        "-b",
        "--board",
        dest="csv_filename",
        help="Specifies the pins.csv filename",
    )
    parser.add_argument(
        "-p",
        "--pins",
        dest="pins_filename",
        help="Specifies the name of the generated pins.c file",
    )
    parser.add_argument(
        "-i",
        "--inc",
        dest="hdr_filename",
        help="Specifies name of generated pin header file",
    )
    args = parser.parse_args(sys.argv[1:])

    pins = Pins()

    if args.csv_filename:
        pins.parse_csv_file(args.csv_filename)

    if args.pins_filename:
        pins.print_pins(args.pins_filename)

    pins.print_header(args.hdr_filename)


if __name__ == "__main__":
    main()
