#!/usr/bin/env python3

# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

"""
Pinctrl Migration Utility Script for nRF Boards
###############################################

This script can be used to automatically migrate the Devicetree files of
nRF-based boards using the old <signal>-pin properties to select peripheral
pins. The script will parse a board Devicetree file and will first adjust that
file by removing old pin-related properties replacing them with pinctrl states.
A board-pinctrl.dtsi file will be generated containing the configuration for
all pinctrl states. Note that script will also work on files that have been
partially ported.

.. warning::
    This script uses a basic line based parser, therefore not all valid
    Devicetree files will be converted correctly. **ADJUSTED/GENERATED FILES
    MUST BE MANUALLY REVIEWED**.

Usage::

    python3 pinctrl_nrf_migrate.py
        -i path/to/board.dts
        [--no-backup]
        [--skip-nrf-check]
        [--header ""]

Example:

.. code-block:: devicetree

    /* Old board.dts */
    ...
    &uart0 {
        ...
        tx-pin = <5>;
        rx-pin = <33>;
        rx-pull-up;
        ...
    };

    /* Adjusted board.dts */
    ...
    #include "board-pinctrl.dtsi"
    ...
    &uart0 {
        ...
        pinctrl-0 = <&uart0_default>;
        pinctrl-1 = <&uart0_sleep>;
        pinctrl-names = "default", "sleep";
        ...
    };

    /* Generated board-pinctrl.dtsi */
    &pinctrl {
        uart0_default: uart0_default {
            group1 {
                psels = <NRF_PSEL(UART_TX, 0, 5);
            };
            group2 {
                psels = <NRF_PSEL(UART_RX, 1, 1)>;
                bias-pull-up;
            };
        };

        uart0_sleep: uart0_sleep {
            group1 {
                psels = <NRF_PSEL(UART_TX, 0, 5)>,
                        <NRF_PSEL(UART_RX, 1, 1)>;
                low-power-enable;
            };
        };
    };
"""

import argparse
import enum
from pathlib import Path
import re
import shutil
from typing import Callable, Optional, Dict, List


#
# Data types and containers
#


class PIN_CONFIG(enum.Enum):
    """Pin configuration attributes"""

    PULL_UP = "bias-pull-up"
    PULL_DOWN = "bias-pull-down"
    LOW_POWER = "low-power-enable"


class Device(object):
    """Device configuration class"""

    def __init__(
        self, pattern: str, callback: Callable, signals: Dict[str, str]
    ) -> None:
        self.pattern = pattern
        self.callback = callback
        self.signals = signals


class SignalMapping(object):
    """Signal mapping (signal<>pin)"""

    def __init__(self, signal: str, pin: int) -> None:
        self.signal = signal
        self.pin = pin


class PinGroup(object):
    """Pin group"""

    def __init__(self, pins: List[SignalMapping], config: List[PIN_CONFIG]) -> None:
        self.pins = pins
        self.config = config


class PinConfiguration(object):
    """Pin configuration (mapping and configuration)"""

    def __init__(self, mapping: SignalMapping, config: List[PIN_CONFIG]) -> None:
        self.mapping = mapping
        self.config = config


class DeviceConfiguration(object):
    """Device configuration"""

    def __init__(self, name: str, pins: List[PinConfiguration]) -> None:
        self.name = name
        self.pins = pins

    def add_signal_config(self, signal: str, config: PIN_CONFIG) -> None:
        """Add configuration to signal"""
        for pin in self.pins:
            if signal == pin.mapping.signal:
                pin.config.append(config)
                return

        self.pins.append(PinConfiguration(SignalMapping(signal, -1), [config]))

    def set_signal_pin(self, signal: str, pin: int) -> None:
        """Set signal pin"""
        for pin_ in self.pins:
            if signal == pin_.mapping.signal:
                pin_.mapping.pin = pin
                return

        self.pins.append(PinConfiguration(SignalMapping(signal, pin), []))


#
# Content formatters and writers
#


def gen_pinctrl(
    configs: List[DeviceConfiguration], input_file: Path, header: str
) -> None:
    """Generate board-pinctrl.dtsi file

    Args:
        configs: Board configs.
        input_file: Board DTS file.
    """

    last_line = 0

    pinctrl_file = input_file.parent / (input_file.stem + "-pinctrl.dtsi")
    # append content before last node closing
    if pinctrl_file.exists():
        content = open(pinctrl_file).readlines()
        for i, line in enumerate(content[::-1]):
            if re.match(r"\s*};.*", line):
                last_line = len(content) - (i + 1)
                break

    out = open(pinctrl_file, "w")

    if not last_line:
        out.write(header)
        out.write("&pinctrl {\n")
    else:
        for line in content[:last_line]:
            out.write(line)

    for config in configs:
        # create pin groups with common configuration (default state)
        default_groups: List[PinGroup] = []
        for pin in config.pins:
            merged = False
            for group in default_groups:
                if group.config == pin.config:
                    group.pins.append(pin.mapping)
                    merged = True
                    break
            if not merged:
                default_groups.append(PinGroup([pin.mapping], pin.config))

        # create pin group for low power state
        group = PinGroup([], [PIN_CONFIG.LOW_POWER])
        for pin in config.pins:
            group.pins.append(pin.mapping)
        sleep_groups = [group]

        # generate default and sleep state entries
        out.write(f"\t{config.name}_default: {config.name}_default {{\n")
        out.write(fmt_pinctrl_groups(default_groups))
        out.write("\t};\n\n")

        out.write(f"\t{config.name}_sleep: {config.name}_sleep {{\n")
        out.write(fmt_pinctrl_groups(sleep_groups))
        out.write("\t};\n\n")

    if not last_line:
        out.write("};\n")
    else:
        for line in content[last_line:]:
            out.write(line)

    out.close()


def board_is_nrf(content: List[str]) -> bool:
    """Check if board is nRF based.

    Args:
        content: DT file content as list of lines.

    Returns:
        True if board is nRF based, False otherwise.
    """

    for line in content:
        m = re.match(r'^#include\s+(?:"|<).*nrf.*(?:>|").*', line)
        if m:
            return True

    return False


def fmt_pinctrl_groups(groups: List[PinGroup]) -> str:
    """Format pinctrl groups.

    Example generated content::

        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 5)>;
        };
        group2 {
            psels = <NRF_PSEL(UART_RX, 1, 1)>;
            bias-pull-up;
        };

    Returns:
        Generated groups.
    """

    content = ""

    for i, group in enumerate(groups):
        content += f"\t\tgroup{i + 1} {{\n"

        # write psels entries
        for i, mapping in enumerate(group.pins):
            prefix = "psels = " if i == 0 else "       "
            suffix = ";" if i == len(group.pins) - 1 else ","
            pin = mapping.pin
            port = 0 if pin < 32 else 1
            if port == 1:
                pin -= 32
            content += (
                f"\t\t\t{prefix}<NRF_PSEL({mapping.signal}, {port}, {pin})>{suffix}\n"
            )

        # write all pin configuration (bias, low-power, etc.)
        for entry in group.config:
            content += f"\t\t\t{entry.value};\n"

        content += "\t\t};\n"

    return content


def fmt_states(device: str, indent: str) -> str:
    """Format state entries for the given device.

    Args:
        device: Device name.
        indent: Intentation.

    Returns:
        State entries to be appended to the device.
    """

    return "\n".join(
        (
            f"{indent}pinctrl-0 = <&{device}_default>;",
            f"{indent}pinctrl-1 = <&{device}_sleep>;",
            f'{indent}pinctrl-names = "default", "sleep";\n',
        )
    )


def insert_pinctrl_include(content: List[str], board: str) -> None:
    """Insert board pinctrl include if not present.

    Args:
        content: DT file content as list of lines.
        board: Board name
    """

    already = False
    include_last_line = -1
    root_line = -1

    for i, line in enumerate(content):
        # check if file already includes a board pinctrl file
        m = re.match(r'^#include\s+".*-pinctrl\.dtsi".*', line)
        if m:
            already = True
            continue

        # check if including
        m = re.match(r'^#include\s+(?:"|<)(.*)(?:>|").*', line)
        if m:
            include_last_line = i
            continue

        # check for root entry
        m = re.match(r"^\s*/\s*{.*", line)
        if m:
            root_line = i
            break

    if include_last_line < 0 and root_line < 0:
        raise ValueError("Unexpected DT file content")

    if not already:
        if include_last_line >= 0:
            line = include_last_line + 1
        else:
            line = max(0, root_line - 1)

        content.insert(line, f'#include "{board}-pinctrl.dtsi"\n')


def adjust_content(content: List[str], board: str) -> List[DeviceConfiguration]:
    """Adjust content

    Args:
        content: File content to be adjusted.
        board: Board name.
    """

    configs: List[DeviceConfiguration] = []
    level = 0
    in_device = False

    new_content = []

    for line in content:
        # look for a device reference node (e.g. &uart0)
        if not in_device:
            m = re.match(r"^[^&]*&([a-z0-9]+)\s*{[^}]*$", line)
            if m:
                # check if device requires processing
                current_device = None
                for device in DEVICES:
                    if re.match(device.pattern, m.group(1)):
                        current_device = device
                        indent = ""
                        config = DeviceConfiguration(m.group(1), [])
                        configs.append(config)
                        break

                # we are now inside a device node
                in_device = True
                level = 1
        else:
            # entering subnode
            if re.match(r"[^\/\*]*{.*", line):
                level += 1
            # exiting subnode (or device node)
            elif re.match(r"[^\/\*]*}.*", line):
                level -= 1
                in_device = level > 0
            elif current_device:
                # device already ported, drop
                if re.match(r"[^\/\*]*pinctrl-\d+.*", line):
                    current_device = None
                    configs.pop()
                # determine indentation
                elif not indent:
                    m = re.match(r"(\s+).*", line)
                    if m:
                        indent = m.group(1)

            # process each device line, append states at the end
            if current_device:
                if in_device:
                    line = current_device.callback(config, current_device.signals, line)
                else:
                    line = fmt_states(config.name, indent) + line
                    current_device = None

        if line:
            new_content.append(line)

    if configs:
        insert_pinctrl_include(new_content, board)

    content[:] = new_content

    return configs


#
# Processing utilities
#


def match_and_store_pin(
    config: DeviceConfiguration, signals: Dict[str, str], line: str
) -> bool:
    """Match and store a pin mapping.

    Args:
        config: Device configuration.
        signals: Signals name mapping.
        line: Line containing potential pin mapping.

    Returns:
        True if line contains a pin mapping, False otherwise.
    """

    m = re.match(r"\s*([a-z]+)-pin\s*=\s*<(\d+)>.*", line)
    if m:
        config.set_signal_pin(signals[m.group(1)], int(m.group(2)))
        return True

    return False


#
# Device processing callbacks
#


def process_uart(config: DeviceConfiguration, signals, line: str) -> Optional[str]:
    """Process UART/UARTE devices."""

    # check if line specifies a pin
    if match_and_store_pin(config, signals, line):
        return None

    # check if pull-up is specified
    m = re.match(r"\s*([a-z]+)-pull-up.*", line)
    if m:
        config.add_signal_config(signals[m.group(1)], PIN_CONFIG.PULL_UP)
        return None

    return line


DEVICES = [
    Device(
        r"uart\d",
        process_uart,
        {
            "tx": "UART_TX",
            "rx": "UART_RX",
            "rts": "UART_RTS",
            "cts": "UART_CTS",
        },
    ),
]
"""Supported devices and associated configuration"""


def main(input_file: Path, no_backup: bool, skip_nrf_check: bool, header: str) -> None:
    """Entry point

    Args:
        input_file: Input DTS file.
        no_backup: Do not create backup files.
    """

    board_name = input_file.stem
    content = open(input_file).readlines()

    if not skip_nrf_check and not board_is_nrf(content):
        print(f"Board {board_name} is not nRF based, terminating")
        return

    if not no_backup:
        backup_file = input_file.parent / (board_name + ".bck" + input_file.suffix)
        shutil.copy(input_file, backup_file)

    configs = adjust_content(content, board_name)

    if configs:
        with open(input_file, "w") as f:
            f.writelines(content)

        gen_pinctrl(configs, input_file, header)

        print(f"Board {board_name} Devicetree file has been converted")
    else:
        print(f"Nothing to be converted for {board_name}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser("pinctrl migration utility for nRF")
    parser.add_argument(
        "-i", "--input", type=Path, required=True, help="Board DTS file"
    )
    parser.add_argument(
        "--no-backup", action="store_true", help="Do not create backup files"
    )
    parser.add_argument(
        "--skip-nrf-check",
        action="store_true",
        help="Skip checking if board is nRF-based",
    )
    parser.add_argument(
        "--header",
        default="",
        type=str,
        help="Header to be prepended to pinctrl files"
    )
    args = parser.parse_args()

    main(args.input, args.no_backup, args.skip_nrf_check, args.header)
