# Copyright 2026 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import os
import sys
import argparse
import tempfile
import re
import subprocess
from pathlib import Path

import kconfig_utils

try:
    import yaml
    try:
        from yaml import CSafeLoader as SafeLoader
    except ImportError:
        from yaml import SafeLoader
except ImportError:
    yaml = None

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--zephyr-base", required=True)
    parser.add_argument("--modules", nargs="+", default=[])
    parser.add_argument("--board-dirs", nargs="+", default=[])
    parser.add_argument("--oot-dts-roots", nargs="+", default=[])
    parser.add_argument("--output", required=True)
    return parser.parse_args()

def find_soc_source_directories(zephyr_base, modules=None):
    soc_roots = [Path(zephyr_base)] + ([Path(m) for m in modules] if modules else [])
    result = []
    for root in soc_roots:
        soc_path = root / 'soc'
        if soc_path.is_dir():
            for dirpath, _, filenames in os.walk(soc_path, followlinks=True):
                if 'soc.yml' in filenames:
                    result.append(dirpath)
    return result

def find_board_source_directories(board_roots):
    result = []
    for root in board_roots:
        root_path = Path(root)
        if not root_path.exists():
            continue
        for dirpath, _, filenames in os.walk(root, followlinks=True):
            if 'board.yml' in filenames:
                result.append(dirpath)
        # HWM v1 uses Kconfig.board or board.Kconfig
        for kconfig_file in root_path.rglob('Kconfig.board'):
             result.append(str(kconfig_file.parent))
        for kconfig_file in root_path.rglob('board.Kconfig'):
             result.append(str(kconfig_file.parent))
    return list(set(result))

def get_soc_to_clusters(soc_dirs):
    """Parses soc.yml files to map SoC names to their clusters."""
    soc_to_clusters = {}
    if yaml is None:
        return soc_to_clusters

    for sdir in soc_dirs:
        soc_yml_path = os.path.join(sdir, "soc.yml")
        if os.path.exists(soc_yml_path):
             try:
                 with open(soc_yml_path, "r") as f:
                     content = yaml.load(f, Loader=SafeLoader)

                     def find_socs(node):
                         if isinstance(node, dict):
                             if "socs" in node:
                                 for soc in node["socs"]:
                                     sn = soc.get("name")
                                     if sn:
                                         if sn not in soc_to_clusters:
                                             soc_to_clusters[sn] = []
                                         if "cpuclusters" in soc:
                                             for cluster in soc["cpuclusters"]:
                                                 cn = cluster.get("name")
                                                 if cn and cn not in soc_to_clusters[sn]:
                                                     soc_to_clusters[sn].append(cn)
                             for v in node.values():
                                 find_socs(v)
                         elif isinstance(node, list):
                             for item in node:
                                 find_socs(item)

                     find_socs(content)
             except Exception as e:
                 raise Exception("DEBUG: Failed to parse %s: %s" % (soc_yml_path, e))
    return soc_to_clusters

def discover_board_variants(board_dirs, soc_to_clusters, symbols):
    """Discovers board and SoC variants from board.yml files using YAML parsing."""
    if yaml is None:
        return

    for bdir in board_dirs:
        for bfile in ["board.yml", "board.yaml"]:
            bpath = os.path.join(bdir, bfile)
            if os.path.exists(bpath):
                try:
                    with open(bpath, "r") as f:
                        content = yaml.load(f, Loader=SafeLoader)

                    if not content:
                        continue

                    # Handle both 'board' (singular) and 'boards' (plural) formats
                    boards = []
                    if isinstance(content.get("board"), dict):
                        boards.append(content["board"])
                    if isinstance(content.get("boards"), list):
                        boards.extend(content["boards"])

                    for board in boards:
                        b_name = board.get("name", "").upper()
                        if not b_name:
                            continue

                        socs = board.get("socs", [])
                        if not isinstance(socs, list):
                            continue

                        for soc in socs:
                            sn_raw = soc.get("name")
                            if not sn_raw:
                                continue

                            sn_upper = sn_raw.upper()
                            base_name = "CONFIG_BOARD_" + kconfig_utils.sanitize_name_for_target(b_name) + "_" + kconfig_utils.sanitize_name_for_target(sn_upper)
                            if base_name not in symbols:
                                symbols[base_name] = "bool"

                            # Add board/soc variants from board.yml
                            variants = soc.get("variants", [])
                            if isinstance(variants, list):
                                for var in variants:
                                    vn_raw = var.get("name")
                                    if vn_raw:
                                        vn_upper = vn_raw.upper()
                                        var_name = base_name + "_" + kconfig_utils.sanitize_name_for_target(vn_upper)
                                        if var_name not in symbols:
                                            symbols[var_name] = "bool"

                            # Add cluster variants
                            if sn_raw in soc_to_clusters:
                                for cn in soc_to_clusters[sn_raw]:
                                    full_name = base_name + "_" + kconfig_utils.sanitize_name_for_target(cn.upper())
                                    if full_name not in symbols:
                                        symbols[full_name] = "bool"
                except Exception as e:
                    raise Exception("DEBUG: Failed to parse %s: %s" % (bpath, e))

def setup_kconfig_environment(zephyr_base, tmp_dir, modules=None):
    """Sets up environment variables required for Kconfig parsing."""
    os.environ["ZEPHYR_BASE"] = zephyr_base
    os.environ["srctree"] = zephyr_base
    os.environ["KCONFIG_BINARY_DIR"] = tmp_dir
    os.environ["CMAKE_BINARY_DIR"] = tmp_dir
    os.environ["HWM_SCHEME"] = "v2"
    os.environ["KCONFIG_FUNCTIONS"] = "kconfigfunctions"
    os.environ["TOOLCHAIN_HAS_PICOLIBC"] = "y"
    os.environ["TOOLCHAIN_HAS_NEWLIB"] = "y"
    os.environ["ZEPHYR_TOOLCHAIN_VARIANT"] = "zephyr"

    kconfig_env_file = os.path.join(tmp_dir, "kconfig_module_dirs.env")
    os.makedirs(tmp_dir, exist_ok=True)
    with open(kconfig_env_file, "w") as f:
        if modules:
            for m in modules:
                if os.path.isdir(m):
                    module_name = os.path.basename(m.rstrip('/')).split('+')[-1].replace('-', '_').upper()
                    m_abs = os.path.abspath(m)
                    f.write(f"ZEPHYR_{module_name}_MODULE_DIR={m_abs}\n")
                    os.environ[f"ZEPHYR_{module_name}_MODULE_DIR"] = m_abs
    os.environ["KCONFIG_ENV_FILE"] = kconfig_env_file

def generate_kconfig_scaffolding(tmp_dir, zephyr_base, soc_dirs, board_dirs, modules, oot_dts_roots=[]):
    """Generates the necessary Kconfig tree scaffolding for super-schema parsing."""
    os.makedirs(tmp_dir, exist_ok=True)

    # Generate aggregation files
    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "soc", "Kconfig.defconfig"), soc_dirs, "SoC defconfigs")
    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "soc", "Kconfig"), soc_dirs, "SoC Kconfigs")
    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "soc", "Kconfig.soc"), soc_dirs, "SoC Kconfigs")
    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "soc", "Kconfig.sysbuild"), soc_dirs, "SoC sysbuild Kconfigs")

    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "boards", "Kconfig.defconfig"), board_dirs, "Board defconfigs")
    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "boards", "Kconfig"), board_dirs, "Board Kconfigs", True)
    kconfig_utils.generate_aggregation_file(os.path.join(tmp_dir, "boards", "Kconfig.sysbuild"), board_dirs, "Board sysbuild Kconfigs")

    # Mock arch Kconfig (Kconfig.zephyr sources it but we'll loop over archs)
    os.makedirs(os.path.join(tmp_dir, "arch"), exist_ok=True)
    with open(os.path.join(tmp_dir, "arch", "Kconfig"), "w") as f:
        f.write("# Placeholder\n")

    kconfig_modules = os.path.join(tmp_dir, "Kconfig.modules")
    kconfig_utils.generate_kconfig_modules(zephyr_base, modules, kconfig_modules)

    dts_roots = [Path(zephyr_base)] + [Path(m) for m in modules] + [Path(r) for r in oot_dts_roots]
    kconfig_utils.generate_kconfig_dts(zephyr_base, os.path.join(tmp_dir, "Kconfig.dts"), dts_roots)

    # Mock currently unsupported parts of the Kconfig tree
    for f_name in ["Kconfig.sysbuild.modules", "Kconfig.shield", "Kconfig.shield.defconfig"]:
        with open(os.path.join(tmp_dir, f_name), "w") as f:
            f.write("# Dummy\n")

def parse_kconfig_authoritative(zephyr_base, tmp_dir, archs, symbols, warnings_list):
    """Uses kconfiglib to perform an authoritative parse for each architecture."""
    # kconfiglib is in Zephyr's scripts/kconfig directory, which is added to path by setup_kconfiglib in main.
    import kconfiglib
    for arch in archs:
        try:
            os.environ["ARCH"] = arch
            os.environ["BOARD"] = "generic"
            os.environ["BOARD_QUALIFIERS"] = ""
            os.environ["SOC_NAME"] = "none"
            os.environ["KCONFIG_BOARD_DIR"] = tmp_dir

            # Update arch/Kconfig mock to source the real arch Kconfig
            with open(os.path.join(tmp_dir, "arch", "Kconfig"), "w") as f:
                arch_kconfig = os.path.join(zephyr_base, "arch", arch, "Kconfig")
                if os.path.exists(arch_kconfig):
                    f.write('source "%s"\n' % arch_kconfig)

            toolchain_arch = "host" if arch == "posix" else "gnuarmemb" if arch == "arm" else "zephyr"
            toolchain_kconfig_dir = os.path.join(zephyr_base, "cmake", "toolchain", toolchain_arch)
            if not os.path.exists(toolchain_kconfig_dir):
                toolchain_kconfig_dir = os.path.join(zephyr_base, "cmake", "toolchain", "zephyr")
            os.environ["TOOLCHAIN_KCONFIG_DIR"] = toolchain_kconfig_dir

            kconf_path = os.path.join(zephyr_base, "Kconfig")
            kconf = kconfiglib.Kconfig(kconf_path)
            if kconf.warnings:
                for warning in kconf.warnings:
                    print("\n" + warning, file=sys.stderr)
                    warnings_list.append(warning)
                print("\nWarnings detected during Kconfig parsing, proceeding anyway.", file=sys.stderr)

            for name, sym in kconf.syms.items():
                if sym.type == kconfiglib.UNKNOWN: continue
                full_name = "CONFIG_" + kconfig_utils.sanitize_name_for_target(name)
                stype = "bool"
                if sym.type in [kconfiglib.INT, kconfiglib.HEX]: stype = "int"
                elif sym.type == kconfiglib.STRING: stype = "string"

                if full_name not in symbols or (stype != "bool" and symbols[full_name] == "bool"):
                    symbols[full_name] = stype
        except Exception as e:
            print("DEBUG: Exception parsing arch %s: %s" % (arch, e), file=sys.stderr)
            pass

def scan_files_for_dynamic_symbols(zephyr_base, board_dirs, modules, symbols):
    """Scans files for symbols that might not be visible in the static Kconfig tree."""
    search_dirs = [zephyr_base] + list(board_dirs) + list(modules)
    for d in search_dirs:
        if not os.path.isdir(d): continue
        for root, _, files in os.walk(d, followlinks=True):
            for fname in files:
                if fname == "Kconfig" or fname.startswith("Kconfig."):
                    try:
                        with open(os.path.join(root, fname), "r", errors="ignore") as f:
                            content = f.read()
                            # config/choice
                            for match in re.finditer(r"^\s*(?:menu)?(?:config|choice)\s+([a-zA-Z0-9_.-]+)", content, re.MULTILINE):
                                name = match.group(1)
                                if name == "MODULES": continue
                                full_name = "CONFIG_" + kconfig_utils.sanitize_name_for_target(name)

                                # Look ahead for type
                                start = match.end()
                                next_match = re.search(r"^\s*(?:menu)?(?:config|choice)\s+", content[start:], re.MULTILINE)
                                end = start + next_match.start() if next_match else len(content)
                                block = content[start:end]

                                stype = None
                                if re.search(r"^\s*int\b", block, re.MULTILINE): stype = "int"
                                elif re.search(r"^\s*hex\b", block, re.MULTILINE): stype = "int"
                                elif re.search(r"^\s*string\b", block, re.MULTILINE): stype = "string"
                                elif re.search(r"^\s*bool\b", block, re.MULTILINE): stype = "bool"

                                if stype:
                                    if full_name not in symbols:
                                        symbols[full_name] = stype
                                    else:
                                        existing_type = symbols[full_name]
                                        if existing_type != stype:
                                            raise Exception(f"Conflict: Symbol {full_name} defined with types '{existing_type}' and '{stype}'")
                                else:
                                    if full_name not in symbols:
                                        symbols[full_name] = "bool"

                            # Logging Template expansion
                            if 'subsys/logging/Kconfig.template.log_config' in content:
                                mod_match = re.search(r"module\s*=\s*([a-zA-Z0-9_]+)", content)
                                if mod_match:
                                    mod_name = mod_match.group(1)
                                    for suffix in ["_LOG_LEVEL_OFF", "_LOG_LEVEL_ERR", "_LOG_LEVEL_WRN", "_LOG_LEVEL_INF", "_LOG_LEVEL_DBG", "_LOG_LEVEL_DEFAULT", "_LOG_LEVEL"]:
                                        full_name = "CONFIG_" + mod_name + suffix
                                        if full_name not in symbols:
                                            symbols[full_name] = "bool" if suffix != "_LOG_LEVEL" else "int"
                    except:
                        pass

def write_bazel_build_file(output_file, symbols):
    """Writes the discovered symbols into a BUILD.bazel file as Bazel flags."""
    with open(output_file, "w") as f:
        f.write('load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "int_flag", "string_flag")\n')
        f.write('load("@rules_cc//cc:defs.bzl", "cc_library")\n')
        f.write('load("@zephyr//:cc.bzl", "zephyr_cc_library")\n\n')
        f.write('package(default_visibility = ["//visibility:public"])\n\n')
        f.write('exports_files(["local_modules.bzl"])\n\n')
        f.write('zephyr_cc_library(\n')
        f.write('    name = "kconfig_warnings",\n')
        f.write('    srcs = ["kconfig_warnings.c"],\n')
        f.write(')\n\n')

        for name in sorted(symbols.keys()):
            stype = symbols[name]
            if stype == "bool":
                f.write('bool_flag(name = "%s", build_setting_default = False)\n' % name)
                f.write('config_setting(name = "%s=true", flag_values = {":%s": "true"})\n' % (name, name))
                f.write('config_setting(name = "%s=false", flag_values = {":%s": "false"})\n' % (name, name))
            elif stype == "int":
                f.write('int_flag(name = "%s", build_setting_default = 0)\n' % name)
                f.write('config_setting(name = "%s=0", flag_values = {":%s": "0"})\n' % (name, name))
            else:
                f.write('string_flag(name = "%s", build_setting_default = "")\n' % name)

def main():
    args = parse_args()
    kconfig_utils.setup_kconfiglib(args.zephyr_base)

    zephyr_base = os.path.abspath(args.zephyr_base)
    tmp_dir = os.path.abspath("kconfig_bin")
    symbols = {}

    # 1. Discover all hardware
    soc_dirs = find_soc_source_directories(zephyr_base, args.modules)
    board_roots = [os.path.join(zephyr_base, 'boards')] + args.board_dirs
    board_dirs = find_board_source_directories(board_roots)

    soc_to_clusters = get_soc_to_clusters(soc_dirs)
    discover_board_variants(board_dirs, soc_to_clusters, symbols)

    arch_root = os.path.join(zephyr_base, "arch")
    archs = [d for d in os.listdir(arch_root) if os.path.isdir(os.path.join(arch_root, d))]

    # 2. Setup environment and scaffolding
    setup_kconfig_environment(zephyr_base, tmp_dir, args.modules)
    generate_kconfig_scaffolding(tmp_dir, zephyr_base, soc_dirs, board_dirs, args.modules, args.oot_dts_roots)

    # 3. Authoritative Parse using kconfiglib
    all_warnings = []
    parse_kconfig_authoritative(zephyr_base, tmp_dir, archs, symbols, all_warnings)

    # Generate kconfig_warnings.c
    output_dir = os.path.dirname(os.path.abspath(args.output))
    with open(os.path.join(output_dir, "kconfig_warnings.c"), "w") as f:
        f.write("/* AUTO-GENERATED by kconfig_gen_symbols.py, do not edit! */\n\n")
        if all_warnings:
            for warning in all_warnings:
                msg = warning.replace('"', '\\"').replace('\n', ' ')
                f.write(f'#warning "Kconfig warning: {msg}"\n')
        else:
            f.write("/* No Kconfig warnings */\n")

    # 4. Fallback: Scan files for dynamic symbols
    scan_files_for_dynamic_symbols(zephyr_base, args.board_dirs, args.modules, symbols)

    # 5. Generate BUILD.bazel
    write_bazel_build_file(args.output, symbols)


if __name__ == "__main__":
    main()
