#!/usr/bin/env python3
#
# Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
# A script to ensure that all declared configuration options match across both
# CMake and Bazel.
#
# Usage:
#
# Run from anywhere.

from dataclasses import dataclass
import glob
import logging
import os
from pathlib import Path
import re
import subprocess
import sys
from typing import Dict

from bazel_common import SDK_ROOT, setup_logging

_LOG = logging.getLogger(__file__)

CMAKE_FILE_TYPES = (
    "**/CMakeLists.txt",
    "**/*.cmake",
)

BAZEL_FILE_TYPES = (
    "**/BUILD.bazel",
    "**/*.bzl",
    "**/*.BUILD",
)

ATTR_REGEX = re.compile(r",?\s*(?P<key>[^=]+)=(?P<value>[^,]+)")

BAZEL_MODULE_REGEX = re.compile(r'\s*commit\s*=\s*\"(?P<commit>[0-9a-fA-F]+)\"\s*,\s*#\s*keep-in-sync-with-submodule:\s*(?P<dependency>\S*)')

BAZEL_VERSION_REGEX = re.compile(r'module\(\s*name\s*=\s*"pico-sdk",\s*version\s*=\s*"(?P<sdk_version>[^"]+)",?\s*\)')

CMAKE_VERSION_REGEX = re.compile(r'^[^#]*set\(PICO_SDK_VERSION_(?P<part>\S+)\s+(?P<value>\S+)\)')

# Sometimes the build systems are supposed to be implemented differently. This
# allowlist permits the descriptions to differ between CMake and Bazel.
BUILD_SYSTEM_DESCRIPTION_DIFFERENCE_ALLOWLIST = (
    # Minor semantic differences in Bazel.
    "PICO_DEFAULT_BOOT_STAGE2_FILE",
    # In Bazel, not overridable by user environment variables (only flags).
    "PICO_BOARD",
    # In Bazel, it's a build label rather than a path.
    "PICO_CMSIS_PATH",
    # In Bazel, the semantics of embedded binary info are slightly different.
    "PICO_PROGRAM_NAME",
    "PICO_PROGRAM_DESCRIPTION",
    "PICO_PROGRAM_URL",
    "PICO_PROGRAM_VERSION_STRING",
    "PICO_TARGET_NAME",
)

CMAKE_ONLY_ALLOWLIST = (
    # Not relevant to Bazel: toolchain is fetched dynamically, and can be
    # overridden with native Bazel features.
    "PICO_TOOLCHAIN_PATH",
    # Bazel uses native --platforms mechanics.
    "PICO_PLATFORM",
    "PICO_DEFAULT_PLATFORM",
    "PICO_DEFAULT_RP2350_PLATFORM",
    # Named PICO_TOOLCHAIN in Bazel.
    "PICO_COMPILER",
    # Bazel uses PICO_COMPILATION_NO_OPT_ARGS and PICO_COMPILATION_NO_DEBUG_ARGS
    # to allow overriding these flags instead.
    "PICO_DEOPTIMIZED_DEBUG",
    "PICO_DEBUG_INFO_IN_RELEASE",
    # Entirely irrelevant to Bazel, use Bazel toolchains:
    #     https://bazel.build/extending/toolchains
    "PICO_TOOLCHAIN_DIR",
    "PICO_GCC_TRIPLE",
    # Entirely irrelevant to Bazel, use Bazel platforms:
    #     https://bazel.build/extending/platforms
    "PICO_CMAKE_PRELOAD_PLATFORM_FILE",
    # Both of these are marked as TODO and not actually set up in CMake.
    "PICO_CMSIS_VENDOR",
    "PICO_CMSIS_DEVICE",
    # Bazel build uses PICO_CONFIG_EXTRA_HEADER and PICO_CONFIG_PLATFORM_HEADER
    # instead.
    "PICO_CONFIG_HEADER_FILES",
    "PICO_RP2040_CONFIG_HEADER_FILES",
    "PICO_HOST_CONFIG_HEADER_FILES",
    "PICO_RP2350_ARM_S_CONFIG_HEADER_FILES",
    "PICO_RP2350_RISCV_CONFIG_HEADER_FILES",
    # Bazel uses PICO_CONFIG_HEADER.
    "PICO_BOARD_CMAKE_DIRS",
    "PICO_BOARD_HEADER_FILE",
    "PICO_BOARD_HEADER_DIRS",
    # Bazel handles default boards differently.
    "PICO_DEFAULT_BOARD_rp2040",
    "PICO_DEFAULT_BOARD_rp2350",
    "PICO_DEFAULT_BOARD_host",
    # Bazel supports this differently.
    # TODO: Provide a helper rule for explicitly generating a UF2 so users don't
    # have to write out a bespoke run_binary.
    "PICO_NO_UF2",
    "PICO_NO_COPRO_DIS",
    "PICO_ALLOW_EXAMPLE_KEYS",
    # Bazel will not provide a default for this.
    # TODO: Provide handy rules for PIOASM so users don't have to write out a
    # bespoke run_binary.
    "PICO_DEFAULT_PIOASM_OUTPUT_FORMAT",
    # Bazel always has picotool.
    "PICO_NO_PICOTOOL",
    # Bazel includes these differently.
    "PICO_TINYUSB_PATH",
    "PICO_BTSTACK_PATH",
    "PICO_CYW43_DRIVER_PATH",
    "PICO_MBEDTLS_PATH",
    "PICO_LWIP_PATH",
    # These are legacy CMake options that should not be used.
    "PICO_NO_FLASH",
    "PICO_COPY_TO_RAM",
)

BAZEL_ONLY_ALLOWLIST = (
    # Allows users to fully replace the final image for boot_stage2.
    "PICO_BOOT_STAGE2_LINK_IMAGE",
    # Allows users to inject an alternative TinyUSB library since TinyUSB
    # doesn't have native Bazel support.
    "PICO_TINYUSB_LIB",
    # Bazel can't do pico_set_* for the binary info defines, so there's a
    # different mechanism.
    "PICO_DEFAULT_BINARY_INFO",
    # Bazel analogue for PICO_CMAKE_BUILD_TYPE.
    "PICO_BAZEL_BUILD_TYPE",
    # Different mechanism for setting a linker script that is less complex.
    "PICO_DEFAULT_LINKER_SCRIPT",
    # Not yet documented in CMake (but probably should be):
    "PICO_CMAKE_BUILD_TYPE",
    # Replaces PICO_RP2040_CONFIG_HEADER_FILES and
    # PICO_HOST_CONFIG_HEADER_FILES.
    "PICO_CONFIG_EXTRA_HEADER",
    "PICO_CONFIG_PLATFORM_HEADER",
    # Effectively replaces:
    # - PICO_BOARD_CMAKE_DIRS
    # - PICO_BOARD_HEADER_FILE
    # - PICO_BOARD_HEADER_DIRS
    "PICO_CONFIG_HEADER",
    # Bazel configuration for 3p deps.
    "PICO_TINYUSB_CONFIG",
    "PICO_BTSTACK_CONFIG",
    "PICO_LWIP_CONFIG",
    "PICO_MBEDTLS_CONFIG",
    "PICO_FREERTOS_LIB",
    "PICO_MBEDTLS_LIB",
    # CMake has PICO_DEFAULT_CLIB, but it's not user-facing.
    "PICO_CLIB",
    # Selecting default library implementations.
    "PICO_MULTICORE_ENABLED",
    "PICO_DEFAULT_DOUBLE_IMPL",
    "PICO_DEFAULT_FLOAT_IMPL",
    "PICO_DEFAULT_DIVIDER_IMPL",
    "PICO_DEFAULT_PRINTF_IMPL",
    "PICO_DEFAULT_RAND_IMPL",
    "PICO_DEFAULT_THREAD_LOCAL_IMPL",
    "PICO_BINARY_INFO_ENABLED",
    "PICO_ASYNC_CONTEXT_IMPL",
    # Allows selection of clang/gcc when using the dynamically fetched
    # toolchains.
    "PICO_TOOLCHAIN",
    # In CMake, linking these libraries also sets defines for adjacent
    # libraries. That's an antipattern in Bazel, so there's flags to control
    # which modules to enable instead.
    "PICO_BT_ENABLE_BLE",
    "PICO_BT_ENABLE_CLASSIC",
    "PICO_BT_ENABLE_MESH",
    # Compilation modes remove, These allow the user to remove the defaults, with no args. See --compilation_mode cmd line option
    "PICO_COMPILATION_NO_OPT_ARGS",
    "PICO_COMPILATION_NO_DEBUG_ARGS",
    "PICO_COMPILATION_NO_FASTBUILD_ARGS",
    # This is commented out in CMake
    "PICO_CMSIS_PATH",
)


@dataclass
class Option:
    name: str
    description: str
    attrs: Dict[str, str]

    def matches(self, other):
        matches = (self.name == other.name) and (self.attrs == other.attrs)
        if not self.name in BUILD_SYSTEM_DESCRIPTION_DIFFERENCE_ALLOWLIST:
            matches = matches and (self.description == other.description)
        return matches


def FindKnownOptions(option_pattern_matcher, file_paths):
    pattern = re.compile(
        option_pattern_matcher
        + r":\s+(?P<name>\w+),\s+(?P<description>[^,]+)(?:,\s+(?P<attrs>.*))?$"
    )
    options = {}
    for p in file_paths:
        with open(p, "r") as f:
            for line in f:
                if re.match("\s*#\s*#", line):
                    # Ignore commented out defines
                    continue

                match = re.search(pattern, line)
                if not match:
                    continue

                attrs = {
                    m.group("key"): m.group("value")
                    for m in re.finditer(ATTR_REGEX, match.group("attrs"))
                }

                options[match.group("name")] = Option(
                    match.group("name"),
                    match.group("description"),
                    attrs,
                )
    return options


def OptionsAreEqual(bazel_option, cmake_option, warnings_as_errors):
    if bazel_option is None:
        if cmake_option.name in CMAKE_ONLY_ALLOWLIST:
            return True
        _LOG.warning(f"    {cmake_option.name} does not exist in Bazel")
        return not warnings_as_errors
    elif cmake_option is None:
        if bazel_option.name in BAZEL_ONLY_ALLOWLIST:
            return True
        _LOG.warning(f"    {bazel_option.name} does not exist in CMake")
        return not warnings_as_errors
    elif not bazel_option.matches(cmake_option):
        _LOG.error("    Bazel and CMAKE definitions do not match:")
        _LOG.error(f"    [CMAKE]    {bazel_option}")
        _LOG.error(f"    [BAZEL]    {cmake_option}")
        return False

    return True


def CompareOptions(bazel_pattern, bazel_files, cmake_pattern, cmake_files, warnings_as_errors=True):
    bazel_options = FindKnownOptions(bazel_pattern, bazel_files)
    cmake_options = FindKnownOptions(cmake_pattern, cmake_files)

    are_equal = True
    both = {}
    both.update(bazel_options)
    both.update(cmake_options)
    for k in both.keys():
        if not OptionsAreEqual(
            bazel_options.get(k, None),
            cmake_options.get(k, None),
            warnings_as_errors,
        ):
            are_equal = False
    return are_equal

def CompareExternalDependencyVersions():
    pattern = re.compile(BAZEL_MODULE_REGEX)
    all_okay = True
    with open(Path(SDK_ROOT) / "MODULE.bazel", "r") as bazel_module_file:
        for line in bazel_module_file:
            maybe_match = pattern.match(line)
            if not maybe_match:
                continue

            current_submodule_pin = subprocess.run(
                ("git", "-C", SDK_ROOT, "rev-parse", f'HEAD:{maybe_match.group("dependency")}'),
                text=True,
                check=True,
                capture_output=True,
            ).stdout.strip()
            if current_submodule_pin != maybe_match.group("commit"):
                _LOG.error("    External pins for %s do not match:", maybe_match.group("dependency"))
                _LOG.error("    [CMAKE]    %s", current_submodule_pin)
                _LOG.error("    [BAZEL]    %s", maybe_match.group("commit"))
                all_okay = False
            else:
                _LOG.info("    External pins for %s match!", maybe_match.group("dependency"))

    return all_okay

def CompareSdkVersion():
    # Find version string specified in Bazel.
    bazel_module_file_path = Path(SDK_ROOT) / "MODULE.bazel"
    bazel_module_file_contents = bazel_module_file_path.read_text()
    bazel_sdk_version = BAZEL_VERSION_REGEX.search(bazel_module_file_contents)
    if not bazel_sdk_version:
        _LOG.error("    Failed to find Bazel Pico SDK version string")
        return False
    bazel_version_string = bazel_sdk_version.group("sdk_version")

    # Find version string specified in CMake.
    cmake_version_parts = {}
    with open(Path(SDK_ROOT) / "pico_sdk_version.cmake", "r") as cmake_version_file:
        for line in cmake_version_file:
            match = CMAKE_VERSION_REGEX.match(line)
            if match:
                cmake_version_parts[match.group("part")] = match.group("value")
    if len(cmake_version_parts) < 3:
        _LOG.error("    Failed to find CMake Pico SDK version string")
        return False
    cmake_version_string = ".".join((
        cmake_version_parts["MAJOR"],
        cmake_version_parts["MINOR"],
        cmake_version_parts["REVISION"],
    ))
    if "PRE_RELEASE_ID" in cmake_version_parts:
        cmake_version_string += "-" + cmake_version_parts["PRE_RELEASE_ID"]

    if cmake_version_string != bazel_version_string:
        _LOG.error("    Declared CMake SDK version is %s and Bazel is %s", cmake_version_string, bazel_version_string)
        return False

    return True

def compare_build_systems():
    cmake_files = [
        f
        for p in CMAKE_FILE_TYPES
        for f in glob.glob(os.path.join(SDK_ROOT, p), recursive=True)
    ]
    bazel_files = [
        f
        for p in BAZEL_FILE_TYPES
        for f in glob.glob(os.path.join(SDK_ROOT, p), recursive=True)
    ]

    results = []
    _LOG.info("[1/3] Checking build system configuration flags...")
    results.append(CompareOptions(
        "PICO_BAZEL_CONFIG",
        bazel_files,
        "PICO_CMAKE_CONFIG",
        cmake_files,
        # For now, allow CMake and Bazel to go out of sync when it comes to
        # build configurability since it's a big ask to make contributors
        # implement the same functionality in both builds.
        warnings_as_errors=False,
    ))

    _LOG.info("[2/4] Checking build system defines...")
    results.append(CompareOptions(
        "PICO_BUILD_DEFINE", bazel_files, "PICO_BUILD_DEFINE", cmake_files
    ))

    _LOG.info("[3/4] Checking submodule pins...")
    results.append(CompareExternalDependencyVersions())

    _LOG.info("[4/4] Checking version strings...")
    results.append(CompareSdkVersion())

    if False not in results:
        _LOG.info("Passed with no blocking failures")
        return 0

    _LOG.error("One or more blocking failures detected")
    return 1


if __name__ == "__main__":
    setup_logging()
    sys.exit(compare_build_systems())
