#!/usr/bin/env python
"""
Utility script to assist in the migration of a board from hardware model v1
(HWMv1) to hardware model v2 (HWMv2).

.. warning::
    This script is not a complete migration tool. It is meant to assist in the
    migration process, but it does not handle all cases.

This script requires the following arguments:

- ``-b|--board``: The name of the board to migrate.
- ``-g|--group``: The group the board belongs to. This is used to group a set of
  boards in the same folder. In HWMv2, the boards are no longer organized by
  architecture.
- ``-v|--vendor``: The vendor name.
- ``-s|--soc``: The SoC name.

In some cases, the new board name will differ from the old board name. For
example, the old board name may have the SoC name as a suffix, while in HWMv2,
this is no longer needed. In such cases, ``-n|--new-board`` needs to be
provided.

For boards with variants, ``--variants`` needs to be provided.

For out-of-tree boards, provide ``--board-root`` pointing to the custom board
root.

Copyright (c) 2023 Nordic Semiconductor ASA
SPDX-License-Identifier: Apache-2.0
"""

import argparse
from pathlib import Path
import re
import sys

import ruamel.yaml


ZEPHYR_BASE = Path(__file__).parents[2]


def board_v1_to_v2(board_root, board, new_board, group, vendor, soc, variants):
    try:
        board_path = next(board_root.glob(f"boards/*/{board}"))
    except StopIteration:
        sys.exit(f"Board not found: {board}")

    new_board_path = board_root / "boards" / group / new_board
    if new_board_path.exists():
        print("New board already exists, updating board with additional SoC")
        if not soc:
            sys.exit("No SoC provided")

    new_board_path.mkdir(parents=True, exist_ok=True)

    print("Moving files to the new board folder...")
    for f in board_path.iterdir():
        f_new = new_board_path / f.name
        if f_new.exists():
            print(f"Skipping existing file: {f_new}")
            continue
        f.rename(f_new)

    print("Creating or updating board.yaml...")
    board_settings_file = new_board_path / "board.yml"
    if not board_settings_file.exists():
        board_settings = {
            "board": {
                "name": new_board,
                "vendor": vendor,
                "socs": []
            }
        }
    else:
        with open(board_settings_file) as f:
            yaml = ruamel.yaml.YAML(typ='safe', pure=True)
            board_settings = yaml.load(f) # pylint: disable=assignment-from-no-return

    soc = {"name": soc}
    if variants:
        soc["variants"] = [{"name": variant} for variant in variants]

    board_settings["board"]["socs"].append(soc)

    yaml = ruamel.yaml.YAML()
    yaml.indent(sequence=4, offset=2)
    with open(board_settings_file, "w") as f:
        yaml.dump(board_settings, f)

    print(f"Updating {board}_defconfig...")
    board_defconfig_file = new_board_path / f"{board}_defconfig"
    with open(board_defconfig_file) as f:
        board_soc_settings = []
        board_defconfig = ""

        dropped_line = False
        for line in f.readlines():
            m = re.match(r"^CONFIG_BOARD_.*$", line)
            if m:
                dropped_line = True
                continue

            m = re.match(r"^CONFIG_(SOC_[A-Z0-9_]+).*$", line)
            if m:
                dropped_line = True
                if not re.match(r"^CONFIG_SOC_SERIES_.*$", line):
                    board_soc_settings.append(m.group(1))
                continue

            if dropped_line and re.match(r"^$", line):
                continue

            dropped_line = False
            board_defconfig += line

    with open(board_defconfig_file, "w") as f:
        f.write(board_defconfig)

    print("Updating Kconfig.defconfig...")
    board_kconfig_defconfig_file = new_board_path / "Kconfig.defconfig"
    with open(board_kconfig_defconfig_file) as f:
        board_kconfig_defconfig = ""
        has_kconfig_defconfig_entries = False

        in_board = False
        for line in f.readlines():
            # drop "config BOARD" entry from Kconfig.defconfig
            m = re.match(r"^config BOARD$", line)
            if m:
                in_board = True
                continue

            if in_board and re.match(r"^\s+.*$", line):
                continue

            in_board = False

            m = re.match(r"^config .*$", line)
            if m:
                has_kconfig_defconfig_entries = True

            m = re.match(rf"^(.*)BOARD_{board.upper()}(.*)$", line)
            if m:
                board_kconfig_defconfig += (
                    m.group(1) + "BOARD_" + new_board.upper() + m.group(2) + "\n"
                )
                continue

            board_kconfig_defconfig += line

    if has_kconfig_defconfig_entries:
        with open(board_kconfig_defconfig_file, "w") as f:
            f.write(board_kconfig_defconfig)
    else:
        print("Removing empty Kconfig.defconfig after update...")
        board_kconfig_defconfig_file.unlink()

    print(f"Creating or updating Kconfig.{new_board}...")
    board_kconfig_file = new_board_path / "Kconfig.board"
    copyright = None
    with open(board_kconfig_file) as f:
        for line in f.readlines():
            if "Copyright" in line:
                copyright = line
    new_board_kconfig_file = new_board_path / f"Kconfig.{new_board}"
    header = "# SPDX-License-Identifier: Apache-2.0\n"
    if copyright is not None:
        header = copyright + header
    selects = "\n\t" + "\n\t".join(["select " + setting for setting in board_soc_settings]) + "\n"
    if not new_board_kconfig_file.exists():
        with open(new_board_kconfig_file, "w") as f:
            f.write(
                header +
                f"\nconfig BOARD_{new_board.upper()}{selects}"
            )
    else:
        with open(new_board_kconfig_file, "a") as f:
            f.write(selects)

    print("Removing old Kconfig.board...")
    board_kconfig_file.unlink()

    print("Conversion done!")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(allow_abbrev=False)

    parser.add_argument(
        "--board-root",
        type=Path,
        default=ZEPHYR_BASE,
        help="Board root",
    )

    parser.add_argument("-b", "--board", type=str, required=True, help="Board name")
    parser.add_argument("-n", "--new-board", type=str, help="New board name")
    parser.add_argument("-g", "--group", type=str, required=True, help="Board group")
    parser.add_argument("-v", "--vendor", type=str, required=True, help="Vendor name")
    parser.add_argument("-s", "--soc", type=str, required=True, help="Board SoC")
    parser.add_argument("--variants", nargs="+", default=[], help="Board variants")

    args = parser.parse_args()

    board_v1_to_v2(
        args.board_root,
        args.board,
        args.new_board or args.board,
        args.group,
        args.vendor,
        args.soc,
        args.variants,
    )
