#!/usr/bin/env python3

# Copyright (c) 2018,2020 Intel Corporation
# Copyright (c) 2022 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

import argparse
import collections
import json
import logging
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys
import tempfile
import textwrap
import traceback
from collections.abc import Iterable
from itertools import takewhile
from pathlib import Path, PurePath

import magic
import unidiff
import yaml
from dotenv import load_dotenv
from junitparser import Error, Failure, JUnitXml, Skipped, TestCase, TestSuite
from reuse.project import Project
from reuse.report import ProjectSubsetReport
from west.manifest import Manifest, ManifestProject
from yamllint import config, linter

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

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import list_boards
import list_hardware
from get_maintainer import Maintainers, MaintainersError

sys.path.insert(
    0, str(Path(__file__).resolve().parents[2] / "scripts" / "dts" / "python-devicetree" / "src")
)
from devicetree import edtlib

# Let the user run this script as ./scripts/ci/check_compliance.py without
# making them set ZEPHYR_BASE.
ZEPHYR_BASE = os.environ.get('ZEPHYR_BASE')
if ZEPHYR_BASE:
    ZEPHYR_BASE = Path(ZEPHYR_BASE)
else:
    ZEPHYR_BASE = Path(__file__).resolve().parents[2]
    # Propagate this decision to child processes.
    os.environ['ZEPHYR_BASE'] = str(ZEPHYR_BASE)

# Initialize the property names allowlist
BINDINGS_PROPERTIES_AL = None
with open(Path(__file__).parents[1] / 'bindings_properties_allowlist.yaml') as f:
    allowlist = yaml.safe_load(f.read())
    if allowlist is not None:
        BINDINGS_PROPERTIES_AL = set(allowlist)
    else:
        BINDINGS_PROPERTIES_AL = set()

logger = None


def git(*args, cwd=None, ignore_non_zero=False):
    # Helper for running a Git command. Returns the rstrip()ed stdout output.
    # Called like git("diff"). Exits with SystemError (raised by sys.exit()) on
    # errors if 'ignore_non_zero' is set to False (default: False). 'cwd' is the
    # working directory to use (default: current directory).

    git_cmd = ("git",) + args
    try:
        cp = subprocess.run(git_cmd, capture_output=True, cwd=cwd)
    except OSError as e:
        err(f"failed to run '{cmd2str(git_cmd)}': {e}")

    if not ignore_non_zero and (cp.returncode or cp.stderr):
        err(
            f"'{cmd2str(git_cmd)}' exited with status {cp.returncode} and/or "
            f"wrote to stderr.\n"
            f"==stdout==\n"
            f"{cp.stdout.decode('utf-8')}\n"
            f"==stderr==\n"
            f"{cp.stderr.decode('utf-8')}\n"
        )

    return cp.stdout.decode("utf-8").rstrip()


def get_shas(refspec):
    """
    Returns the list of Git SHAs for 'refspec'.

    :param refspec:
    :return:
    """
    return git('rev-list', f'--max-count={-1 if "." in refspec else 1}', refspec).split()


def get_files(filter=None, paths=None):
    filter_arg = (f'--diff-filter={filter}',) if filter else ()
    paths_arg = ('--', *paths) if paths else ()
    out = git('diff', '--name-only', *filter_arg, COMMIT_RANGE, *paths_arg)
    files = out.splitlines()
    for file in list(files):
        if not (GIT_TOP / file).exists():
            # Drop submodule directories from the list.
            files.remove(file)
    return files


def get_module_setting_root(root, settings_file):
    """
    Parse the Zephyr module generated settings file given by 'settings_file'
    and return all root settings defined by 'root'.
    """
    # Invoke the script directly using the Python executable since this is
    # not a module nor a pip-installed Python utility
    root_paths = []

    if os.path.exists(settings_file):
        with open(settings_file) as fp_setting_file:
            content = fp_setting_file.read()

        lines = content.strip().split('\n')
        for line in lines:
            root = root.upper()
            if line.startswith(f'"{root}_ROOT":'):
                _, root_path = line.split(":", 1)
                root_paths.append(Path(root_path.strip('"')))
    return root_paths


def get_vendor_prefixes(path, errfn=print) -> set[str]:
    vendor_prefixes = set()
    with open(path) as fp:
        for line in fp.readlines():
            line = line.strip()
            if not line or line.startswith("#"):
                continue
            try:
                vendor, _ = line.split("\t", 2)
                vendor_prefixes.add(vendor)
            except ValueError:
                errfn(f"Invalid line in {path}:\"{line}\".")
                errfn("Did you forget the tab character?")
    return vendor_prefixes


def zephyr_doc_detail_builder(doc_subpath: str) -> str:
    return f"See https://docs.zephyrproject.org/latest{doc_subpath} for more details."


class FmtdFailure(Failure):
    def __init__(
        self, severity, title, file, line=None, col=None, desc="", end_line=None, end_col=None
    ):
        self.severity = severity
        self.title = title
        self.file = file
        self.line = line
        self.col = col
        self.end_line = end_line
        self.end_col = end_col
        self.desc = desc
        description = f':{desc}' if desc else ''
        msg_body = desc or title

        txt = (
            f'\n{title}{description}\nFile:{file}'
            + (f'\nLine:{line}' if line else '')
            + (f'\nColumn:{col}' if col else '')
            + (f'\nEndLine:{end_line}' if end_line else '')
            + (f'\nEndColumn:{end_col}' if end_col else '')
        )
        msg = f'{file}' + (f':{line}' if line else '') + f' {msg_body}'
        typ = severity.lower()

        super().__init__(msg, typ)

        self.text = txt


class ComplianceTest:
    """
    Base class for tests. Inheriting classes should have a run() method and set
    these class variables:

    name:
      Test name

    doc:
      Link to documentation related to what's being tested

    path_hint:
      The path the test runs itself in. By default it uses the magic string
      "<git-top>" which refers to the top-level repository directory.

      This avoids running 'git' to find the top-level directory before main()
      runs (class variable assignments run when the 'class ...' statement
      runs). That avoids swallowing errors, because main() reports them to
      GitHub.

      Subclasses may override the default with a specific path or one of the
      magic strings below:
      - "<zephyr-base>" can be used to refer to the environment variable
        ZEPHYR_BASE or, when missing, the calculated base of the zephyr tree.
    """

    path_hint = "<git-top>"

    def __init__(self):
        self.case = TestCase(type(self).name, "Guidelines")
        # This is necessary because Failure can be subclassed, but since it is
        # always restored form the element tree, the subclass is lost upon
        # restoring
        self.fmtd_failures = []

    def _result(self, res, text):
        res.text = text.rstrip()
        self.case.result += [res]

    def error(self, text, msg=None, type_="error"):
        """
        Signals a problem with running the test, with message 'msg'.

        Raises an exception internally, so you do not need to put a 'return'
        after error().
        """
        err = Error(msg or f'{type(self).name} error', type_)
        self._result(err, text)

        raise EndTest

    def skip(self, text, msg=None, type_="skip"):
        """
        Signals that the test should be skipped, with message 'msg'.

        Raises an exception internally, so you do not need to put a 'return'
        after skip().
        """
        skpd = Skipped(msg or f'{type(self).name} skipped', type_)
        self._result(skpd, text)

        raise EndTest

    def failure(self, text, msg=None, type_="failure"):
        """
        Signals that the test failed, with message 'msg'. Can be called many
        times within the same test to report multiple failures.
        """
        fail = Failure(msg or f'{type(self).name} issues', type_)
        self._result(fail, text)

    def fmtd_failure(
        self, severity, title, file, line=None, col=None, desc="", end_line=None, end_col=None
    ):
        """
        Signals that the test failed, and store the information in a formatted
        standardized manner. Can be called many times within the same test to
        report multiple failures.
        """
        fail = FmtdFailure(severity, title, file, line, col, desc, end_line, end_col)
        self._result(fail, fail.text)
        self.fmtd_failures.append(fail)


class EndTest(Exception):
    """
    Raised by ComplianceTest.error()/skip() to end the test.

    Tests can raise EndTest themselves to immediately end the test, e.g. from
    within a nested function call.
    """


class CheckPatch(ComplianceTest):
    """
    Runs checkpatch and reports found issues

    """

    name = "Checkpatch"
    doc = zephyr_doc_detail_builder("/contribute/guidelines.html#coding-style")

    def run(self):
        checkpatch = ZEPHYR_BASE / 'scripts' / 'checkpatch.pl'
        if not checkpatch.exists():
            self.skip(f'{checkpatch} not found')

        # check for Perl installation on Windows
        if os.name == 'nt':
            if not shutil.which('perl'):
                err = "Perl not installed - required for checkpatch.pl. "
                err += "Please install Perl or add to PATH."
                self.failure(err)
                return
            else:
                cmd = ['perl', checkpatch]

        # Linux and MacOS
        else:
            cmd = [checkpatch]

        cmd.extend(['--mailback', '--no-tree', '-'])
        with subprocess.Popen(
            ('git', 'diff', '--no-ext-diff', COMMIT_RANGE), stdout=subprocess.PIPE, cwd=GIT_TOP
        ) as diff:
            try:
                subprocess.run(
                    cmd,
                    check=True,
                    stdin=diff.stdout,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    shell=False,
                    cwd=GIT_TOP,
                )

            except subprocess.CalledProcessError as ex:
                output = ex.output.decode("utf-8")
                regex = (
                    r'^\s*\S+:(\d+):\s*(ERROR|WARNING):(.+?):(.+)(?:\n|\r\n?)+'
                    r'^\s*#(\d+):\s*FILE:\s*(.+):(\d+):'
                )

                matches = re.findall(regex, output, re.MULTILINE)

                # add a guard here for excessive number of errors, do not try and
                # process each one of them and instead push this as one failure.
                if len(matches) > 500:
                    self.failure(output)
                    return

                for m in matches:
                    self.fmtd_failure(m[1].lower(), m[2], m[5], m[6], col=None, desc=m[3])

                # If the regex has not matched add the whole output as a failure
                if len(matches) == 0:
                    self.failure(output)


class BoardYmlCheck(ComplianceTest):
    """
    Check the board.yml files
    """

    name = "BoardYml"
    doc = "Check the board.yml file format"

    def check_board_file(self, file, vendor_prefixes):
        """Validate a single board file."""
        with open(file) as fp:
            for line_num, line in enumerate(fp.readlines(), start=1):
                if "vendor:" in line:
                    _, vnd = line.strip().split(":", 2)
                    vnd = vnd.strip()
                    if vnd not in vendor_prefixes:
                        desc = f"invalid vendor: {vnd}"
                        self.fmtd_failure("error", "BoardYml", file, line_num, desc=desc)

    def run(self):
        path = resolve_path_hint(self.path_hint)
        module_ymls = [path / "zephyr" / "module.yml", path / "zephyr" / "module.yaml"]

        vendor_prefixes = {"others"}
        # add vendor prefixes from the main zephyr repo
        vendor_prefix_file = ZEPHYR_BASE / "dts" / "bindings" / "vendor-prefixes.txt"
        vendor_prefixes |= get_vendor_prefixes(vendor_prefix_file, self.error)
        # add vendor prefixes from the current repo
        dts_root = None
        for module_yml in module_ymls:
            if module_yml.is_file():
                with module_yml.open('r', encoding='utf-8') as f:
                    meta = yaml.load(f.read(), Loader=SafeLoader)
                    section = meta.get('build', dict())
                    build_settings = section.get('settings', None)
                    if build_settings:
                        dts_root = build_settings.get('dts_root', None)

        if dts_root:
            vendor_prefix_file = Path(dts_root) / "dts" / "bindings" / "vendor-prefixes.txt"
            if vendor_prefix_file.exists():
                vendor_prefixes |= get_vendor_prefixes(vendor_prefix_file, self.error)

        for file in path.glob("**/board.yml"):
            self.check_board_file(file, vendor_prefixes)


class ClangFormatCheck(ComplianceTest):
    """
    Check if clang-format reports any issues
    """

    name = "ClangFormat"
    doc = zephyr_doc_detail_builder("/contribute/guidelines.html#clang-format")

    def _process_patch_error(self, file: str, patch: unidiff.PatchedFile):
        for hunk in patch:
            # Strip the before and after context
            before = next(i for i, v in enumerate(hunk) if str(v).startswith(('-', '+')))
            after = next(i for i, v in enumerate(reversed(hunk)) if str(v).startswith(('-', '+')))
            msg = "".join([str(line) for line in hunk[before : -after or None]])

            # show the hunk at the last line
            self.fmtd_failure(
                "notice",
                "You may want to run clang-format on this change",
                file,
                line=hunk.source_start + hunk.source_length - after,
                desc=f'\r\n{msg}',
            )

    def run(self):
        exe = f"clang-format-diff.{'exe' if platform.system() == 'Windows' else 'py'}"

        for file in get_files():
            if Path(file).suffix not in ['.c', '.h']:
                continue

            diff = subprocess.Popen(
                ('git', 'diff', '-U0', '--no-color', COMMIT_RANGE, '--', file),
                stdout=subprocess.PIPE,
                cwd=GIT_TOP,
            )
            try:
                subprocess.run(
                    (exe, '-p1'),
                    check=True,
                    stdin=diff.stdout,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    cwd=GIT_TOP,
                )

            except subprocess.CalledProcessError as ex:
                patchset = unidiff.PatchSet.from_string(ex.output, encoding="utf-8")
                for patch in patchset:
                    self._process_patch_error(file, patch)


class DevicetreeBindingsCheck(ComplianceTest):
    """
    Checks if we are introducing any unwanted properties in Devicetree Bindings.
    """

    name = "DevicetreeBindings"
    doc = zephyr_doc_detail_builder("/build/dts/bindings.html")

    def run(self, full=True):
        bindings_diff, bindings = self.get_yaml_bindings()

        # If no bindings are changed, skip this check.
        try:
            subprocess.check_call(['git', 'diff', '--quiet', COMMIT_RANGE] + bindings_diff)
            nodiff = True
        except subprocess.CalledProcessError:
            nodiff = False
        if nodiff:
            self.skip('no changes to bindings were made')

        for binding in bindings:
            self.check(binding, self.check_yaml_property_name)
            self.check(binding, self.required_false_check)

    @staticmethod
    def check(binding, callback):
        while binding is not None:
            callback(binding)
            binding = binding.child_binding

    def get_yaml_bindings(self):
        """
        Returns a list of 'dts/bindings/**/*.yaml'
        """
        from glob import glob

        BINDINGS_PATH = 'dts/bindings/'
        bindings_diff_dir, bindings = set(), []

        for file_name in get_files(filter='d'):
            if BINDINGS_PATH in file_name:
                p = file_name.partition(BINDINGS_PATH)
                bindings_diff_dir.add(os.path.join(p[0], p[1]))

        for path in bindings_diff_dir:
            yamls = glob(f'{os.fspath(path)}/**/*.yaml', recursive=True)
            bindings.extend(yamls)

        bindings = edtlib.bindings_from_paths(bindings, ignore_errors=True)
        return list(bindings_diff_dir), bindings

    def check_yaml_property_name(self, binding):
        """
        Checks if the property names in the binding file contain underscores.
        """
        for prop_name in binding.prop2specs:
            if '_' in prop_name and prop_name not in BINDINGS_PROPERTIES_AL:
                better_prop = prop_name.replace('_', '-')
                print(
                    f"Required: In '{binding.path}', "
                    f"the property '{prop_name}' "
                    f"should be renamed to '{better_prop}'."
                )
                self.failure(
                    f"{binding.path}: property '{prop_name}' contains underscores.\n"
                    f"\tUse '{better_prop}' instead unless this property name is from Linux.\n"
                    "Or another authoritative upstream source of bindings for "
                    f"compatible '{binding.compatible}'.\n"
                    "\tHint: update 'bindings_properties_allowlist.yaml' if you need to "
                    "override this check for this property."
                )

    def required_false_check(self, binding):
        raw_props = binding.raw.get('properties', {})
        for prop_name, raw_prop in raw_props.items():
            if raw_prop.get('required') is False:
                self.failure(
                    f'{binding.path}: property "{prop_name}": '
                    "'required: false' is redundant, please remove"
                )


class DevicetreeLintingCheck(ComplianceTest):
    """
    Checks if we are introducing syntax or formatting issues to devicetree files.
    """

    name = "DevicetreeLinting"
    doc = zephyr_doc_detail_builder("/contribute/style/devicetree.html")
    NPX_EXECUTABLE = "npx"

    def ensure_npx(self) -> bool:
        if not (npx_executable := shutil.which(self.NPX_EXECUTABLE)):
            return False
        try:
            self.npx_exe = npx_executable
            # --no prevents npx from fetching from registry
            subprocess.run(
                [self.npx_exe, "--prefix", "./scripts/ci", "--no", 'dts-linter', "--", "--version"],
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL,
                check=True,
                text=True,
            )
            return True
        except subprocess.CalledProcessError:
            return False

    def _parse_json_output(self, cmd, cwd=None):
        """Run command and parse single JSON output with issues array"""
        result = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            check=False,
            text=True,
            cwd=cwd or GIT_TOP,
        )

        if not result.stdout.strip():
            return None

        try:
            json_data = json.loads(result.stdout)
            return json_data
        except json.JSONDecodeError as e:
            raise RuntimeError(f"Failed to parse dts-linter JSON output: {e}") from e

    def _process_json_output(self, json_output: dict):
        if "issues" not in json_output:
            return

        cwd = json_output.get("cwd", "")
        logging.info(f"Processing issues from: {cwd}")

        for issue in json_output["issues"]:
            level = issue.get("level", "unknown")
            message = issue.get("message", "")

            if level == "info":
                logging.info(message)
            else:
                title = issue.get("title", "")
                file = issue.get("file", "")
                line = issue.get("startLine", None)
                col = issue.get("startCol", None)
                end_line = issue.get("endLine", None)
                end_col = issue.get("endCol", None)
                self.fmtd_failure(level, title, file, line, col, message, end_line, end_col)

    def run(self):
        self.npx_exe = self.NPX_EXECUTABLE
        # Get changed DTS files
        dts_files = [
            file for file in get_files(filter="d") if file.endswith((".dts", ".dtsi", ".overlay"))
        ]

        if not self.ensure_npx():
            self.skip(
                'dts-linter not installed. To run this check, '
                'install Node.js and then run [npm ci] command inside ZEPHYR_BASE'
            )
        if not dts_files:
            self.skip('No DTS')

        temp_patch_files = []
        batch_size = 500

        for i in range(0, len(dts_files), batch_size):
            batch = dts_files[i : i + batch_size]

            # use a temporary file for each batch
            temp_patch = f"dts_linter_{i}.patch"
            temp_patch_files.append(temp_patch)

            cmd = [
                self.npx_exe,
                "--prefix",
                "./scripts/ci",
                "--no",
                "dts-linter",
                "--",
                "--outputFormat",
                "json",
                "--format",
                "--patchFile",
                temp_patch,
            ]
            for file in batch:
                cmd.extend(["--file", file])

            try:
                json_output = self._parse_json_output(cmd)
                if json_output:
                    self._process_json_output(json_output)

            except subprocess.CalledProcessError as ex:
                stderr_output = ex.stderr if ex.stderr else ""
                if stderr_output.strip():
                    self.failure(f"dts-linter found issues:\n{stderr_output}")
                else:
                    err = "dts-linter failed with no output. "
                    err += "Make sure you install Node.js and then run npm ci inside ZEPHYR_BASE"
                    self.failure(err)
            except RuntimeError as ex:
                self.failure(f"{ex}")

        # merge all temp patch files into one
        with open("dts_linter.patch", "wb") as final_patch:
            for patch in temp_patch_files:
                with open(patch, "rb") as f:
                    shutil.copyfileobj(f, final_patch)

        # cleanup
        for patch in temp_patch_files:
            os.remove(patch)


class KconfigCheck(ComplianceTest):
    """
    Checks is we are introducing any new warnings/errors with Kconfig,
    for example using undefined Kconfig variables.
    """

    name = "Kconfig"
    doc = zephyr_doc_detail_builder("/build/kconfig/tips.html")

    # Top-level Kconfig file. The path can be relative to srctree (ZEPHYR_BASE).
    FILENAME = "Kconfig"

    # Kconfig symbol prefix/namespace.
    CONFIG_ = "CONFIG_"

    def run(self):
        kconf = self.parse_kconfig()

        self.check_top_menu_not_too_long(kconf)
        self.check_no_pointless_menuconfigs(kconf)
        self.check_no_undef_within_kconfig(kconf)
        self.check_no_redefined_in_defconfig(kconf)
        self.check_no_enable_in_boolean_prompt(kconf)
        self.check_soc_name_sync(kconf)
        self.check_no_undef_outside_kconfig(kconf)
        self.check_disallowed_defconfigs(kconf)

    def get_modules(self, _module_dirs_file, modules_file, sysbuild_modules_file, settings_file):
        """
        Get a list of modules and put them in a file that is parsed by
        Kconfig

        This is needed to complete Kconfig sanity tests.

        """
        # Invoke the script directly using the Python executable since this is
        # not a module nor a pip-installed Python utility
        zephyr_module_path = ZEPHYR_BASE / "scripts" / "zephyr_module.py"
        cmd = [
            sys.executable,
            zephyr_module_path,
            '--kconfig-out',
            modules_file,
            '--sysbuild-kconfig-out',
            sysbuild_modules_file,
            '--settings-out',
            settings_file,
        ]
        try:
            subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as ex:
            self.error(ex.output.decode("utf-8"))

        modules_dir = ZEPHYR_BASE / 'modules'
        modules = [name for name in os.listdir(modules_dir) if modules_dir / name / 'Kconfig']

        with open(modules_file) as fp_module_file:
            content = fp_module_file.read()

        with open(modules_file, 'w') as fp_module_file:
            for module in modules:
                fp_module_file.write(
                    "ZEPHYR_{}_KCONFIG = {}\n".format(
                        re.sub('[^a-zA-Z0-9]', '_', module).upper(),
                        modules_dir / module / 'Kconfig',
                    )
                )
            fp_module_file.write(content)

    def get_kconfig_dts(self, kconfig_dts_file, settings_file):
        """
        Generate the Kconfig.dts using dts/bindings as the source.

        This is needed to complete Kconfig compliance tests.

        """
        # Invoke the script directly using the Python executable since this is
        # not a module nor a pip-installed Python utility
        zephyr_drv_kconfig_path = ZEPHYR_BASE / "scripts" / "dts" / "gen_driver_kconfig_dts.py"
        binding_paths = []
        binding_paths.append(ZEPHYR_BASE / "dts" / "bindings")

        dts_root_paths = get_module_setting_root('dts', settings_file)
        for p in dts_root_paths:
            binding_paths.append(p / "dts" / "bindings")

        cmd = [
            sys.executable,
            zephyr_drv_kconfig_path,
            '--kconfig-out',
            kconfig_dts_file,
            '--bindings-dirs',
        ]
        for binding_path in binding_paths:
            cmd.append(binding_path)
        try:
            subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as ex:
            self.error(ex.output.decode("utf-8"))

    def get_v2_model(self, kconfig_dir, settings_file):
        """
        Get lists of v2 boards and SoCs and put them in a file that is parsed by
        Kconfig

        This is needed to complete Kconfig sanity tests.
        """
        os.environ['HWM_SCHEME'] = 'v2'
        os.environ["KCONFIG_BOARD_DIR"] = os.path.join(kconfig_dir, 'boards')

        os.makedirs(os.path.join(kconfig_dir, 'boards'), exist_ok=True)
        os.makedirs(os.path.join(kconfig_dir, 'soc'), exist_ok=True)
        os.makedirs(os.path.join(kconfig_dir, 'arch'), exist_ok=True)

        kconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig')
        kconfig_boards_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.boards')
        kconfig_sysbuild_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.sysbuild')
        kconfig_defconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.defconfig')

        board_roots = get_module_setting_root('board', settings_file)
        board_roots.insert(0, ZEPHYR_BASE)
        soc_roots = get_module_setting_root('soc', settings_file)
        soc_roots.insert(0, ZEPHYR_BASE)
        root_args = argparse.Namespace(
            **{'board_roots': board_roots, 'soc_roots': soc_roots, 'board': None, 'board_dir': []}
        )
        v2_boards = list_boards.find_v2_boards(root_args).values()

        with open(kconfig_defconfig_file, 'w') as fp:
            for board in v2_boards:
                for board_dir in board.directories:
                    fp.write('osource "' + (board_dir / 'Kconfig.defconfig').as_posix() + '"\n')

        with open(kconfig_sysbuild_file, 'w') as fp:
            for board in v2_boards:
                for board_dir in board.directories:
                    fp.write('osource "' + (board_dir / 'Kconfig.sysbuild').as_posix() + '"\n')

        with open(kconfig_boards_file, 'w') as fp:
            for board in v2_boards:
                board_str = 'BOARD_' + re.sub(r"[^a-zA-Z0-9_]", "_", board.name).upper()
                fp.write('config  ' + board_str + '\n')
                fp.write('\t bool\n')
                for qualifier in list_boards.board_v2_qualifiers(board):
                    board_str = (
                        'BOARD_' + board.name + '_' + re.sub(r"[^a-zA-Z0-9_]", "_", qualifier)
                    ).upper()
                    fp.write('config  ' + board_str + '\n')
                    fp.write('\t bool\n')
                for board_dir in board.directories:
                    fp.write(
                        'source "' + (board_dir / ('Kconfig.' + board.name)).as_posix() + '"\n'
                    )

        with open(kconfig_file, 'w') as fp:
            for board in v2_boards:
                for board_dir in board.directories:
                    fp.write('osource "' + (board_dir / 'Kconfig').as_posix() + '"\n')

        kconfig_defconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.defconfig')
        kconfig_sysbuild_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.sysbuild')
        kconfig_soc_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.soc')
        kconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig')

        root_args = argparse.Namespace(**{'soc_roots': soc_roots})
        v2_systems = list_hardware.find_v2_systems(root_args)

        soc_folders = {folder for soc in v2_systems.get_socs() for folder in soc.folder}
        with open(kconfig_defconfig_file, 'w') as fp:
            for folder in soc_folders:
                fp.write('osource "' + (Path(folder) / 'Kconfig.defconfig').as_posix() + '"\n')

        with open(kconfig_sysbuild_file, 'w') as fp:
            for folder in soc_folders:
                fp.write('osource "' + (Path(folder) / 'Kconfig.sysbuild').as_posix() + '"\n')

        with open(kconfig_soc_file, 'w') as fp:
            for folder in soc_folders:
                fp.write('source "' + (Path(folder) / 'Kconfig.soc').as_posix() + '"\n')

        with open(kconfig_file, 'w') as fp:
            for folder in soc_folders:
                fp.write('source "' + (Path(folder) / 'Kconfig').as_posix() + '"\n')

        kconfig_file = os.path.join(kconfig_dir, 'arch', 'Kconfig')

        root_args = argparse.Namespace(**{'arch_roots': [ZEPHYR_BASE], 'arch': None})
        v2_archs = list_hardware.find_v2_archs(root_args)

        with open(kconfig_file, 'w') as fp:
            for arch in v2_archs['archs']:
                fp.write('source "' + (Path(arch['path']) / 'Kconfig').as_posix() + '"\n')

    def parse_kconfig(self):
        """
        Returns a kconfiglib.Kconfig object for the Kconfig files. We reuse
        this object for all tests to avoid having to reparse for each test.
        """
        # Put the Kconfiglib path first to make sure no local Kconfiglib version is
        # used
        kconfig_path = ZEPHYR_BASE / "scripts" / "kconfig"
        if not kconfig_path.exists():
            self.error(kconfig_path + " not found")

        kconfiglib_dir = tempfile.mkdtemp(prefix="kconfiglib_")

        sys.path.insert(0, str(kconfig_path))
        # Import globally so that e.g. kconfiglib.Symbol can be referenced in
        # tests
        global kconfiglib
        import kconfiglib

        # Look up Kconfig files relative to ZEPHYR_BASE
        os.environ["srctree"] = str(ZEPHYR_BASE)  # noqa: SIM112

        # Parse the entire Kconfig tree, to make sure we see all symbols
        os.environ["SOC_DIR"] = "soc/"
        os.environ["ARCH_DIR"] = "arch/"
        os.environ["BOARD"] = "boards"
        os.environ["ARCH"] = "*"
        os.environ["KCONFIG_BINARY_DIR"] = kconfiglib_dir
        os.environ['DEVICETREE_CONF'] = "dummy"
        os.environ['TOOLCHAIN_HAS_NEWLIB'] = "y"
        kconfig_env_file = os.path.join(kconfiglib_dir, "kconfig_module_dirs.env")

        # Older name for DEVICETREE_CONF, for compatibility with older Zephyr
        # versions that don't have the renaming
        os.environ["GENERATED_DTS_BOARD_CONF"] = "dummy"

        # For multi repo support
        self.get_modules(
            kconfig_env_file,
            os.path.join(kconfiglib_dir, "Kconfig.modules"),
            os.path.join(kconfiglib_dir, "Kconfig.sysbuild.modules"),
            os.path.join(kconfiglib_dir, "settings_file.txt"),
        )
        # For Kconfig.dts support
        self.get_kconfig_dts(
            os.path.join(kconfiglib_dir, "Kconfig.dts"),
            os.path.join(kconfiglib_dir, "settings_file.txt"),
        )
        # For hardware model support (board, soc, arch)
        self.get_v2_model(kconfiglib_dir, os.path.join(kconfiglib_dir, "settings_file.txt"))

        # Tells Kconfiglib to generate warnings for all references to undefined
        # symbols within Kconfig files
        os.environ["KCONFIG_WARN_UNDEF"] = "y"

        load_dotenv(kconfig_env_file)

        try:
            # Note this will both print warnings to stderr _and_ return
            # them: so some warnings might get printed
            # twice. "warn_to_stderr=False" could unfortunately cause
            # some (other) warnings to never be printed.
            return kconfiglib.Kconfig(filename=self.FILENAME)
        except kconfiglib.KconfigError as e:
            self.failure(str(e))
            raise EndTest from e
        finally:
            # Clean up the temporary directory
            shutil.rmtree(kconfiglib_dir)

    def module_kconfigs(self, regex):
        manifest = Manifest.from_file()
        kconfigs = ""

        # Use hard coded paths for Zephyr for tests, samples and ext. module root
        tmp_output = git(
            "grep",
            "-I",
            "-h",
            "--perl-regexp",
            regex,
            "--",
            ":tests",
            ":samples",
            ":modules",
            cwd=ZEPHYR_BASE,
            ignore_non_zero=True,
        )

        if len(tmp_output) > 0:
            kconfigs += tmp_output + "\n"

        for project in manifest.get_projects([]):
            if not manifest.is_active(project):
                continue

            if not project.is_cloned():
                continue

            module_path = PurePath(project.abspath)
            module_yml = module_path.joinpath('zephyr/module.yml')

            if not Path(module_yml).is_file():
                module_yml = module_path.joinpath('zephyr/module.yaml')

            if Path(module_yml).is_file():
                dirs = []

                with Path(module_yml).open('r', encoding='utf-8') as f:
                    meta = yaml.load(f.read(), Loader=SafeLoader)

                for folder_type in ['samples', 'tests']:
                    if folder_type in meta:
                        for path_ext in meta[folder_type]:
                            path_full = module_path.joinpath(path_ext)

                            if Path(path_full).is_dir():
                                dirs.append(":" + path_ext)

                # Add ext. module root, if one is defined
                if (
                    'build' in meta
                    and 'settings' in meta['build']
                    and 'module_ext_root' in meta['build']['settings']
                ):
                    path_full = module_path.joinpath(meta['build']['settings']['module_ext_root'])

                    if Path(path_full).is_dir():
                        dirs.append(":" + meta['build']['settings']['module_ext_root'])

                if len(dirs) > 0:
                    tmp_output = git(
                        "grep",
                        "-I",
                        "-h",
                        "--perl-regexp",
                        regex,
                        "--",
                        *dirs,
                        cwd=module_path,
                        ignore_non_zero=True,
                    )

                    if len(tmp_output) > 0:
                        kconfigs += tmp_output + "\n"

        return kconfigs

    def get_logging_syms(self, kconf):
        # Returns a set() with the names of the Kconfig symbols generated with
        # logging template in samples/tests folders. The Kconfig symbols doesn't
        # include `CONFIG_` and for each module declared there is one symbol
        # per suffix created.

        suffixes = [
            "_LOG_LEVEL",
            "_LOG_LEVEL_DBG",
            "_LOG_LEVEL_ERR",
            "_LOG_LEVEL_INF",
            "_LOG_LEVEL_WRN",
            "_LOG_LEVEL_OFF",
            "_LOG_LEVEL_INHERIT",
            "_LOG_LEVEL_DEFAULT",
        ]

        # Warning: Needs to work with both --perl-regexp and the 're' module.
        regex = r"^\s*(?:module\s*=\s*)([A-Z0-9_]+)\s*(?:#|$)"

        # Grep samples/ and tests/ for symbol definitions in all modules
        grep_stdout = self.module_kconfigs(regex)

        names = re.findall(regex, grep_stdout, re.MULTILINE)

        kconf_syms = []
        for name in names:
            for suffix in suffixes:
                kconf_syms.append(f"{name}{suffix}")

        return set(kconf_syms)

    def module_disallowed_check(self, module_path, type, folder, meta, regex):
        # Returns a list with lines from git grep which includes Kconfigs from defconfig files
        entry = type + '_root'
        git_folder = ":" + folder

        if entry in meta['build']['settings']:
            tmp_path = module_path.joinpath(meta['build']['settings'][entry])

            if Path(tmp_path.joinpath(folder)).is_dir():
                tmp_output = git(
                    "grep",
                    "--line-number",
                    "-I",
                    "--null",
                    "--perl-regexp",
                    regex,
                    "--",
                    git_folder,
                    cwd=tmp_path,
                    ignore_non_zero=True,
                )

                if len(tmp_output) > 0:
                    return tmp_output.splitlines()
        return []

    def check_disallowed_defconfigs(self, kconf):
        """
        Checks that there are no disallowed Kconfigs used in board/SoC defconfig files
        """
        # Grep for symbol references.
        #
        # Example output line for a reference to CONFIG_FOO at line 17 of
        # foo/bar.c:
        #
        #   foo/bar.c<null>17<null>#ifdef CONFIG_FOO
        #
        # 'git grep --only-matching' would get rid of the surrounding context
        # ('#ifdef '), but it was added fairly recently (second half of 2018),
        # so we extract the references from each line ourselves instead.
        #
        # The regex uses word boundaries (\b) to isolate the reference, and
        # negative lookahead to automatically allowlist the following:
        #
        #  - ##, for token pasting (CONFIG_FOO_##X)
        #
        #  - $, e.g. for CMake variable expansion (CONFIG_FOO_${VAR})
        #
        #  - @, e.g. for CMakes's configure_file() (CONFIG_FOO_@VAR@)
        #
        #  - {, e.g. for Python scripts ("CONFIG_FOO_{}_BAR".format(...)")
        #
        #  - *, meant for comments like '#endif /* CONFIG_FOO_* */

        disallowed_symbols = {
            "PINCTRL": "Drivers requiring PINCTRL must SELECT it instead.",
            "BOARD_EARLY_INIT_HOOK": "Boards requiring hooks must SELECT them instead.",
            "BOARD_LATE_INIT_HOOK": "Boards requiring hooks must SELECT them instead.",
        }

        disallowed_regex = "(" + "|".join(disallowed_symbols.keys()) + ")$"

        # Warning: Needs to work with both --perl-regexp and the 're' module
        # Windows
        if os.name == 'nt':
            # Remove word boundaries on Windows implementation
            regex_boards = r"CONFIG_[A-Z0-9_]+(?!\s*##|[$@{(.*])"
            regex_socs = r"config[ \t]+[A-Z0-9_]+"
        else:
            regex_boards = r"\bCONFIG_[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"
            regex_socs = r"\bconfig\s+[A-Z0-9_]+$"

        grep_stdout_boards = git(
            "grep",
            "--line-number",
            "-I",
            "--null",
            "--perl-regexp",
            regex_boards,
            "--",
            ":boards",
            cwd=ZEPHYR_BASE,
        ).splitlines()
        grep_stdout_socs = git(
            "grep",
            "--line-number",
            "-I",
            "--null",
            "--perl-regexp",
            regex_socs,
            "--",
            ":soc",
            cwd=ZEPHYR_BASE,
        ).splitlines()

        manifest = Manifest.from_file()
        for project in manifest.get_projects([]):
            if not manifest.is_active(project):
                continue

            if not project.is_cloned():
                continue

            module_path = PurePath(project.abspath)
            module_yml = module_path.joinpath('zephyr/module.yml')

            if not Path(module_yml).is_file():
                module_yml = module_path.joinpath('zephyr/module.yaml')

            if Path(module_yml).is_file():
                with Path(module_yml).open('r', encoding='utf-8') as f:
                    meta = yaml.load(f.read(), Loader=SafeLoader)

                    if 'build' in meta and 'settings' in meta['build']:
                        grep_stdout_boards.extend(
                            self.module_disallowed_check(
                                module_path, 'board', 'boards', meta, regex_boards
                            )
                        )
                        grep_stdout_socs.extend(
                            self.module_disallowed_check(
                                module_path, 'soc', 'soc', meta, regex_socs
                            )
                        )

        # Board processing
        # splitlines() supports various line terminators
        for grep_line in grep_stdout_boards:
            path, lineno, line = grep_line.split("\0")

            # Extract symbol references (might be more than one) within the line
            for sym_name in re.findall(regex_boards, line):
                sym_name = sym_name[len("CONFIG_") :]
                # Only check in Kconfig fragment files, references might exist in documentation
                if re.match(disallowed_regex, sym_name) and (
                    path[-len("conf") :] == "conf" or path[-len("defconfig") :] == "defconfig"
                ):
                    reason = disallowed_symbols.get(sym_name)
                    self.fmtd_failure(
                        "error",
                        "BoardDisallowedKconfigs",
                        path,
                        lineno,
                        desc=f"""
Found disallowed Kconfig symbol in board Kconfig files: CONFIG_{sym_name:35}
{reason}
""",
                    )

        # SoCs processing
        # splitlines() supports various line terminators
        for grep_line in grep_stdout_socs:
            path, lineno, line = grep_line.split("\0")

            # Extract symbol references (might be more than one) within the line
            for sym_name in re.findall(regex_socs, line):
                sym_name = sym_name[len("config") :].strip()
                # Only check in Kconfig defconfig files
                if re.match(disallowed_regex, sym_name) and "defconfig" in path:
                    reason = disallowed_symbols.get(sym_name, "Unknown reason")
                    self.fmtd_failure(
                        "error",
                        "SoCDisallowedKconfigs",
                        path,
                        lineno,
                        desc=f"""
Found disallowed Kconfig symbol in SoC Kconfig files: {sym_name:35}
{reason}
""",
                    )

    def get_defined_syms(self, kconf):
        # Returns a set() with the names of all defined Kconfig symbols (with no
        # 'CONFIG_' prefix). This is complicated by samples and tests defining
        # their own Kconfig trees. For those, just grep for 'config FOO' to find
        # definitions. Doing it "properly" with Kconfiglib is still useful for
        # the main tree, because some symbols are defined using preprocessor
        # macros.

        # Warning: Needs to work with both --perl-regexp and the 're' module.
        # (?:...) is a non-capturing group.
        regex = r"^\s*(?:menu)?config\s*([A-Z0-9_]+)\s*(?:#|$)"

        # Grep samples/ and tests/ for symbol definitions in all modules
        grep_stdout = self.module_kconfigs(regex)

        # Generate combined list of configs and choices from the main Kconfig tree.
        kconf_syms = kconf.unique_defined_syms + kconf.unique_choices

        # Symbols from the main Kconfig tree + grepped definitions from samples
        # and tests
        return set(
            [sym.name for sym in kconf_syms] + re.findall(regex, grep_stdout, re.MULTILINE)
        ).union(self.get_logging_syms(kconf))

    def check_top_menu_not_too_long(self, kconf):
        """
        Checks that there aren't too many items in the top-level menu (which
        might be a sign that stuff accidentally got added there)
        """
        max_top_items = 50

        n_top_items = 0
        node = kconf.top_node.list
        while node:
            # Only count items with prompts. Other items will never be
            # shown in the menuconfig (outside show-all mode).
            if node.prompt:
                n_top_items += 1
            node = node.next

        if n_top_items > max_top_items:
            self.failure(f"""
Expected no more than {max_top_items} potentially visible items (items with
prompts) in the top-level Kconfig menu, found {n_top_items} items. If you're
deliberately adding new entries, then bump the 'max_top_items' variable in
{__file__}.""")

    def check_no_redefined_in_defconfig(self, kconf):
        # Checks that no symbols are (re)defined in defconfigs.

        for node in kconf.node_iter():
            # 'kconfiglib' is global
            # pylint: disable=undefined-variable
            if "defconfig" in node.filename and (node.prompt or node.help):
                name = (
                    node.item.name
                    if node.item not in (kconfiglib.MENU, kconfiglib.COMMENT)
                    else str(node)
                )
                self.failure(f"""
Kconfig node '{name}' found with prompt or help in {node.filename}.
Options must not be defined in defconfig files.
""")
                continue

    def check_no_enable_in_boolean_prompt(self, kconf):
        # Checks that boolean's prompt does not start with "Enable...".

        for node in kconf.node_iter():
            # skip Kconfig nodes not in-tree (will present an absolute path)
            if os.path.isabs(node.filename):
                continue

            # 'kconfiglib' is global
            # pylint: disable=undefined-variable

            # only process boolean symbols with a prompt
            if (
                not isinstance(node.item, kconfiglib.Symbol)
                or node.item.type != kconfiglib.BOOL
                or not node.prompt
                or not node.prompt[0]
            ):
                continue

            if re.match(r"^[Ee]nable.*", node.prompt[0]):
                self.failure(f"""
Boolean option '{node.item.name}' prompt must not start with 'Enable...'. Please
check Kconfig guidelines.
""")
                continue

    def check_no_pointless_menuconfigs(self, kconf):
        # Checks that there are no pointless 'menuconfig' symbols without
        # children in the Kconfig files

        bad_mconfs = []
        for node in kconf.node_iter():
            # 'kconfiglib' is global
            # pylint: disable=undefined-variable

            # Avoid flagging empty regular menus and choices, in case people do
            # something with 'osource' (could happen for 'menuconfig' symbols
            # too, though it's less likely)
            if node.is_menuconfig and not node.list and isinstance(node.item, kconfiglib.Symbol):
                bad_mconfs.append(node)

        if bad_mconfs:
            self.failure(
                """\
Found pointless 'menuconfig' symbols without children. Use regular 'config'
symbols instead. See
https://docs.zephyrproject.org/latest/build/kconfig/tips.html#menuconfig-symbols.

"""
                + "\n".join(
                    f"{node.item.name:35} {node.filename}:{node.linenr}" for node in bad_mconfs
                )
            )

    def check_no_undef_within_kconfig(self, kconf):
        """
        Checks that there are no references to undefined Kconfig symbols within
        the Kconfig files
        """
        undef_ref_warnings = "\n\n\n".join(
            warning for warning in kconf.warnings if "undefined symbol" in warning
        )

        if undef_ref_warnings:
            self.failure(f"Undefined Kconfig symbols:\n\n {undef_ref_warnings}")

    def check_soc_name_sync(self, kconf):
        root_args = argparse.Namespace(**{'soc_roots': [ZEPHYR_BASE]})
        v2_systems = list_hardware.find_v2_systems(root_args)

        soc_names = {soc.name for soc in v2_systems.get_socs()}

        soc_kconfig_names = set()
        for node in kconf.node_iter():
            # 'kconfiglib' is global
            # pylint: disable=undefined-variable
            if isinstance(node.item, kconfiglib.Symbol) and node.item.name == "SOC":
                n = node.item
                for d in n.defaults:
                    soc_kconfig_names.add(d[0].name)

        soc_name_warnings = []
        for name in soc_names:
            if name not in soc_kconfig_names:
                soc_name_warnings.append(f"soc name: {name} not found in CONFIG_SOC defaults.")

        if soc_name_warnings:
            soc_name_warning_str = '\n'.join(soc_name_warnings)
            self.failure(f'''
Missing SoC names or CONFIG_SOC vs soc.yml out of sync:

{soc_name_warning_str}
''')

    def check_no_undef_outside_kconfig(self, kconf):
        """
        Checks that there are no references to undefined Kconfig symbols
        outside Kconfig files (any CONFIG_FOO where no FOO symbol exists)
        """
        # Grep for symbol references.
        #
        # Example output line for a reference to CONFIG_FOO at line 17 of
        # foo/bar.c:
        #
        #   foo/bar.c<null>17<null>#ifdef CONFIG_FOO
        #
        # 'git grep --only-matching' would get rid of the surrounding context
        # ('#ifdef '), but it was added fairly recently (second half of 2018),
        # so we extract the references from each line ourselves instead.
        #
        # The regex uses word boundaries (\b) to isolate the reference, and
        # negative lookahead to automatically allowlist the following:
        #
        #  - ##, for token pasting (CONFIG_FOO_##X)
        #
        #  - $, e.g. for CMake variable expansion (CONFIG_FOO_${VAR})
        #
        #  - @, e.g. for CMakes's configure_file() (CONFIG_FOO_@VAR@)
        #
        #  - {, e.g. for Python scripts ("CONFIG_FOO_{}_BAR".format(...)")
        #
        #  - *, meant for comments like '#endif /* CONFIG_FOO_* */

        defined_syms = self.get_defined_syms(kconf)

        # Maps each undefined symbol to a list <filename>:<linenr> strings
        undef_to_locs = collections.defaultdict(list)

        # Warning: Needs to work with both --perl-regexp and the 're' module
        regex = r"\b" + self.CONFIG_ + r"[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"

        # Skip doc/releases and doc/security/vulnerabilities.rst, which often
        # reference removed symbols
        grep_stdout = git(
            "grep",
            "--line-number",
            "-I",
            "--null",
            "--perl-regexp",
            regex,
            "--",
            ":!/doc/releases",
            ":!/doc/security/vulnerabilities.rst",
            cwd=GIT_TOP,
        )

        # splitlines() supports various line terminators
        for grep_line in grep_stdout.splitlines():
            path, lineno, line = grep_line.split("\0")

            # Extract symbol references (might be more than one) within the
            # line
            for sym_name in re.findall(regex, line):
                sym_name = sym_name[len(self.CONFIG_) :]  # Strip CONFIG_
                if (
                    sym_name not in defined_syms
                    and sym_name not in self.UNDEF_KCONFIG_ALLOWLIST
                    and not (sym_name.endswith("_MODULE") and sym_name[:-7] in defined_syms)
                    and not sym_name.startswith("BOARD_REVISION_")
                ):
                    undef_to_locs[sym_name].append(f"{path}:{lineno}")

        if not undef_to_locs:
            return

        # String that describes all referenced but undefined Kconfig symbols,
        # in alphabetical order, along with the locations where they're
        # referenced. Example:
        #
        #   CONFIG_ALSO_MISSING    arch/xtensa/core/fatal.c:273
        #   CONFIG_MISSING         arch/xtensa/core/fatal.c:264, subsys/fb/cfb.c:20
        undef_desc = "\n".join(
            f"{self.CONFIG_}{sym_name:35} {', '.join(locs)}"
            for sym_name, locs in sorted(undef_to_locs.items())
        )

        self.failure(f"""
Found references to undefined Kconfig symbols. If any of these are false
positives, then add them to UNDEF_KCONFIG_ALLOWLIST in {__file__}.

If the reference is for a comment like /* CONFIG_FOO_* */ (or
/* CONFIG_FOO_*_... */), then please use exactly that form (with the '*'). The
CI check knows not to flag it.

More generally, a reference followed by $, @, {{, (, ., *, or ## will never be
flagged.

{undef_desc}""")

    # Many of these are symbols used as examples. Note that the list is sorted
    # alphabetically, and skips the CONFIG_ prefix.
    UNDEF_KCONFIG_ALLOWLIST = {
        # zephyr-keep-sorted-start re(^\s+")
        "ALSO_MISSING",
        "APP_LINK_WITH_",
        # Application log level is not detected correctly as
        # the option is defined using a template, so it can't
        # be grepped
        "APP_LOG_LEVEL",
        "APP_LOG_LEVEL_DBG",
        # The ARMCLANG_STD_LIBC is defined in the
        # toolchain Kconfig which is sourced based on
        # Zephyr toolchain variant and therefore not
        # visible to compliance.
        "ARMCLANG_STD_LIBC",
        "BINDESC_",  # Used in documentation as a prefix
        "BOARD_",  # Used as regex in scripts/utils/board_v1_to_v2.py
        "BOARD_MPS2_AN521_CPUTEST",  # Used for board and SoC extension feature tests
        "BOARD_NATIVE_SIM_NATIVE_64_TWO",  # Used for board and SoC extension feature tests
        "BOARD_NATIVE_SIM_NATIVE_ONE",  # Used for board and SoC extension feature tests
        "BOARD_UNIT_TESTING",  # Used for tests/unit
        "BOOT_DIRECT_XIP",  # Used in sysbuild for MCUboot configuration
        "BOOT_DIRECT_XIP_REVERT",  # Used in sysbuild for MCUboot configuration
        "BOOT_ENCRYPTION_KEY_FILE",  # Used in sysbuild
        "BOOT_ENCRYPT_ALG_AES_128",  # Used in sysbuild
        "BOOT_ENCRYPT_ALG_AES_256",  # Used in sysbuild
        "BOOT_ENCRYPT_IMAGE",  # Used in sysbuild
        "BOOT_FIRMWARE_LOADER",  # Used in sysbuild for MCUboot configuration
        "BOOT_FIRMWARE_LOADER_BOOT_MODE",  # Used in sysbuild for MCUboot configuration
        "BOOT_IMAGE_EXECUTABLE_RAM_SIZE",  # MCUboot setting
        "BOOT_IMAGE_EXECUTABLE_RAM_START",  # MCUboot setting
        "BOOT_MAX_IMG_SECTORS_AUTO",  # Used in sysbuild
        "BOOT_RAM_LOAD",  # Used in sysbuild for MCUboot configuration
        "BOOT_RAM_LOAD_REVERT",  # Used in sysbuild for MCUboot configuration
        "BOOT_SERIAL_BOOT_MODE",  # Used in (sysbuild-based) test/documentation
        "BOOT_SERIAL_CDC_ACM",  # Used in (sysbuild-based) test
        "BOOT_SERIAL_ENTRANCE_GPIO",  # Used in (sysbuild-based) test
        "BOOT_SERIAL_IMG_GRP_HASH",  # Used in documentation
        "BOOT_SERIAL_UART",  # Used in (sysbuild-based) test
        "BOOT_SHARE_BACKEND_RETENTION",  # Used in Kconfig text
        "BOOT_SHARE_DATA",  # Used in Kconfig text
        "BOOT_SHARE_DATA_BOOTINFO",  # Used in (sysbuild-based) test
        "BOOT_SIGNATURE_KEY_FILE",  # MCUboot setting used by sysbuild
        "BOOT_SIGNATURE_TYPE_ECDSA_P256",  # MCUboot setting used by sysbuild
        "BOOT_SIGNATURE_TYPE_ED25519",  # MCUboot setting used by sysbuild
        "BOOT_SIGNATURE_TYPE_NONE",  # MCUboot setting used by sysbuild
        "BOOT_SIGNATURE_TYPE_RSA",  # MCUboot setting used by sysbuild
        "BOOT_SWAP_USING_MOVE",  # Used in sysbuild for MCUboot configuration
        "BOOT_SWAP_USING_OFFSET",  # Used in sysbuild for MCUboot configuration
        "BOOT_SWAP_USING_SCRATCH",  # Used in sysbuild for MCUboot configuration
        # Used in example adjusting MCUboot config, but
        # symbol is defined in MCUboot itself.
        "BOOT_UPGRADE_ONLY",
        "BOOT_VALIDATE_SLOT0",  # Used in (sysbuild-based) test
        "BOOT_WATCHDOG_FEED",  # Used in (sysbuild-based) test
        "BT_6LOWPAN",  # Defined in Linux, mentioned in docs
        "CDC_ACM_PORT_NAME_",
        "CHRE",  # Optional module
        "CHRE_LOG_LEVEL_DBG",  # Optional module
        "CLOCK_STM32_SYSCLK_SRC_",
        "CMD_CACHE",  # Defined in U-Boot, mentioned in docs
        "CMU",
        "COMPILER_RT_RTLIB",
        "CRC",  # Used in TI CC13x2 / CC26x2 SDK comment
        "DEEP_SLEEP",  # #defined by RV32M1 in ext/
        "DESCRIPTION",
        "ERR",
        "ESP_DIF_LIBRARY",  # Referenced in CMake comment
        "EXPERIMENTAL",
        "EXTRA_FIRMWARE_DIR",  # Linux, in boards/xtensa/intel_adsp_cavs25/doc
        "FFT",  # Used as an example in cmake/extensions.cmake
        "FLAG",  # Used as an example
        "FOO",
        "FOO_LOG_LEVEL",
        "FOO_SETTING_1",
        "FOO_SETTING_2",
        "HEAP_MEM_POOL_ADD_SIZE_",  # Used as an option matching prefix
        "HUGETLBFS",  # Linux, in boards/xtensa/intel_adsp_cavs25/doc
        "IAR_BUFFERED_WRITE",
        "IAR_DATA_INIT",
        "IAR_LIBCPP",
        "IAR_SEMIHOSTING",
        "IAR_ZEPHYR_INIT",
        # Used in ICMsg tests for intercompatibility
        # with older versions of the ICMsg.
        "IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS",
        "LIBGCC_RTLIB",
        "LLVM_USE_LD",  # Both LLVM_USE_* are in cmake/toolchain/llvm/Kconfig
        # which are only included if LLVM is selected but
        # not other toolchains. Compliance check would complain,
        # for example, if you are using GCC.
        "LLVM_USE_LLD",
        "LOG_BACKEND_MOCK_OUTPUT_DEFAULT",  # Referenced in tests/subsys/logging/log_syst
        "LOG_BACKEND_MOCK_OUTPUT_SYST",  # Referenced in testcase.yaml of log_syst test
        "LSM6DSO_INT_PIN",
        "MCUBOOT_ACTION_HOOKS",  # Used in (sysbuild-based) test
        "MCUBOOT_CLEANUP_ARM_CORE",  # Used in (sysbuild-based) test
        "MCUBOOT_DOWNGRADE_PREVENTION",  # but symbols are defined in MCUboot itself.
        "MCUBOOT_LOG_LEVEL_DBG",
        "MCUBOOT_LOG_LEVEL_INF",
        "MCUBOOT_LOG_LEVEL_WRN",  # Used in example adjusting MCUboot config,
        "MCUBOOT_SERIAL",  # Used in (sysbuild-based) test/documentation
        "MCUMGR_GRP_EXAMPLE_OTHER_HOOK",  # Used in documentation
        # Used in modules/hal_nxp/mcux/mcux-sdk-ng/device/device.cmake.
        # It is a variable used by MCUX SDK CMake.
        "MCUX_HW_CORE",
        # Used in modules/hal_nxp/mcux/mcux-sdk-ng/device/device.cmake.
        # It is a variable used by MCUX SDK CMake.
        "MCUX_HW_DEVICE_CORE",
        # Used in modules/hal_nxp/mcux/mcux-sdk-ng/device/device.cmake.
        # It is a variable used by MCUX SDK CMake.
        "MCUX_HW_FPU_TYPE",
        "MISSING",
        "MODULES",
        "MODVERSIONS",  # Linux, in boards/xtensa/intel_adsp_cavs25/doc
        "MYFEATURE",
        "MY_DRIVER_0",
        "NORMAL_SLEEP",  # #defined by RV32M1 in ext/
        "NRF_WIFI_FW_BIN",  # Directly passed from CMakeLists.txt
        "OPT",
        "OPT_0",
        "PEDO_THS_MIN",
        "PSA_H",  # This is used in config-psa.h as guard for the header file
        "REG1",
        "REG2",
        "RIMAGE_SIGNING_SCHEMA",  # Optional module
        "SECURITY_LOADPIN",  # Linux, in boards/xtensa/intel_adsp_cavs25/doc
        "SEL",
        "SHIFT",
        "SINGLE_APPLICATION_SLOT",  # Used in sysbuild for MCUboot configuration
        "SINGLE_APPLICATION_SLOT_RAM_LOAD",  # Used in sysbuild for MCUboot configuration
        "SOC_NORDIC_BSP_PATH_OVERRIDE",  # Used in modules/hal_nordic/nrfx/CMakeLists.txt
        "SOC_SDKNG_UNSUPPORTED",  # Used in modules/hal_nxp/mcux/CMakeLists.txt
        "SOC_SERIES_",  # Used as regex in scripts/utils/board_v1_to_v2.py
        "SOC_WATCH",  # Issue 13749
        "SOME_BOOL",
        "SOME_INT",
        "SOME_OTHER_BOOL",
        "SOME_STRING",
        "SRAM2",  # Referenced in a comment in samples/application_development
        "STACK_SIZE",  # Used as an example in the Kconfig docs
        "STD_CPP",  # Referenced in CMake comment
        "TEST1",
        # Defined in modules/hal_nxp/mcux/mcux-sdk-ng/basic.cmake.
        # It is used by MCUX SDK cmake functions to add content
        # based on current toolchain.
        "TOOLCHAIN",
        # The symbol is defined in the toolchain
        # Kconfig which is sourced based on Zephyr
        # toolchain variant and therefore not visible
        # to compliance.
        "TOOLCHAIN_ARCMWDT_SUPPORTS_THREAD_LOCAL_STORAGE",
        "TYPE_BOOLEAN",
        "USB_CONSOLE",
        "USE_STDC_",
        "WHATEVER",
        "ZEPHYR_TRY_MASS_ERASE",  # MCUBoot setting described in sysbuild documentation
        "ZTEST_FAIL_TEST_",  # regex in tests/ztest/fail/CMakeLists.txt
        "ZVFS_OPEN_ADD_SIZE_",  # Used as an option matching prefix
        # zephyr-keep-sorted-stop
    }


class KconfigBasicCheck(KconfigCheck):
    """
    Checks if we are introducing any new warnings/errors with Kconfig,
    for example using undefined Kconfig variables.
    This runs the basic Kconfig test, which is checking only for undefined
    references inside the Kconfig tree.
    """

    name = "KconfigBasic"

    def check_no_undef_outside_kconfig(self, kconf):
        pass


class KconfigBasicNoModulesCheck(KconfigBasicCheck):
    """
    Checks if we are introducing any new warnings/errors with Kconfig when no
    modules are available. Catches symbols used in the main repository but
    defined only in a module.
    """

    name = "KconfigBasicNoModules"
    path_hint = "<zephyr-base>"
    EMPTY_FILE_CONTENTS = "# Empty\n"

    def get_modules(self, module_dirs_file, modules_file, sysbuild_modules_file, settings_file):
        with open(module_dirs_file, 'w') as fp_module_file:
            fp_module_file.write(self.EMPTY_FILE_CONTENTS)

        with open(modules_file, 'w') as fp_module_file:
            fp_module_file.write(self.EMPTY_FILE_CONTENTS)

        with open(sysbuild_modules_file, 'w') as fp_module_file:
            fp_module_file.write(self.EMPTY_FILE_CONTENTS)


class KconfigHWMv2Check(KconfigBasicCheck):
    """
    This runs the Kconfig test for board and SoC v2 scheme.
    This check ensures that all symbols inside the v2 scheme is also defined
    within the same tree.
    This ensures the board and SoC trees are fully self-contained and reusable.
    """

    name = "KconfigHWMv2"

    # Use dedicated Kconfig board / soc v2 scheme file.
    # This file sources only v2 scheme tree.
    FILENAME = os.path.join(os.path.dirname(__file__), "Kconfig.board.v2")


class SysbuildKconfigCheck(KconfigCheck):
    """
    Checks if we are introducing any new warnings/errors with sysbuild Kconfig,
    for example using undefined Kconfig variables.
    """

    name = "SysbuildKconfig"

    FILENAME = "share/sysbuild/Kconfig"
    CONFIG_ = "SB_CONFIG_"

    # A different allowlist is used for symbols prefixed with SB_CONFIG_ (omitted here).
    UNDEF_KCONFIG_ALLOWLIST = {
        # zephyr-keep-sorted-start re(^\s+")
        "FOO",
        "MY_IMAGE",  # Used in sysbuild documentation as example
        "OTHER_APP_IMAGE_NAME",  # Used in sysbuild documentation as example
        "OTHER_APP_IMAGE_PATH",  # Used in sysbuild documentation as example
        "SECOND_SAMPLE",  # Used in sysbuild documentation
        # zephyr-keep-sorted-stop
    }


class SysbuildKconfigBasicCheck(SysbuildKconfigCheck, KconfigBasicCheck):
    """
    Checks if we are introducing any new warnings/errors with sysbuild Kconfig,
    for example using undefined Kconfig variables.
    This runs the basic Kconfig test, which is checking only for undefined
    references inside the sysbuild Kconfig tree.
    """

    name = "SysbuildKconfigBasic"


class SysbuildKconfigBasicNoModulesCheck(SysbuildKconfigCheck, KconfigBasicNoModulesCheck):
    """
    Checks if we are introducing any new warnings/errors with sysbuild Kconfig
    when no modules are available. Catches symbols used in the main repository
    but defined only in a module.
    """

    name = "SysbuildKconfigBasicNoModules"
    path_hint = "<zephyr-base>"


class Nits(ComplianceTest):
    """
    Checks various nits in added/modified files. Doesn't check stuff that's
    already covered by e.g. checkpatch.pl and pylint.
    """

    name = "Nits"
    doc = zephyr_doc_detail_builder("/contribute/guidelines.html#coding-style")

    def run(self):
        # Loop through added/modified files
        for fname in get_files(filter="d"):
            if "Kconfig" in fname:
                self.check_kconfig_header(fname)
                self.check_redundant_zephyr_source(fname)

            if fname.startswith("dts/bindings/"):
                self.check_redundant_document_separator(fname)

            if (
                fname.endswith(
                    (
                        ".c",
                        ".conf",
                        ".cpp",
                        ".dts",
                        ".overlay",
                        ".h",
                        ".ld",
                        ".py",
                        ".rst",
                        ".txt",
                        ".yaml",
                        ".yml",
                    )
                )
                or "Kconfig" in fname
                or "defconfig" in fname
                or fname == "README"
            ):
                self.check_source_file(fname)

    def check_kconfig_header(self, fname):
        # Checks for a spammy copy-pasted header format

        with open(GIT_TOP / fname, encoding="utf-8") as f:
            contents = f.read()

        # 'Kconfig - yada yada' has a copy-pasted redundant filename at the
        # top. This probably means all of the header was copy-pasted.
        if re.match(r"\s*#\s*(K|k)config[\w.-]*\s*-", contents):
            self.failure(f"""
Please use this format for the header in '{fname}' (see
https://docs.zephyrproject.org/latest/build/kconfig/tips.html#header-comments-and-other-nits):

    # <Overview of symbols defined in the file, preferably in plain English>
    (Blank line)
    # Copyright (c) 2019 ...
    # SPDX-License-Identifier: <License>
    (Blank line)
    (Kconfig definitions)

Skip the "Kconfig - " part of the first line, since it's clear that the comment
is about Kconfig from context. The "# Kconfig - " is what triggers this
failure.
""")

    def check_redundant_zephyr_source(self, fname):
        # Checks for 'source "$(ZEPHYR_BASE)/Kconfig[.zephyr]"', which can be
        # be simplified to 'source "Kconfig[.zephyr]"'

        with open(GIT_TOP / fname, encoding="utf-8") as f:
            # Look for e.g. rsource as well, for completeness
            match = re.search(
                r'^\s*(?:o|r|or)?source\s*"\$\(?ZEPHYR_BASE\)?/(Kconfig(?:\.zephyr)?)"',
                f.read(),
                re.MULTILINE,
            )

            if match:
                self.failure(
                    """
Redundant 'source "$(ZEPHYR_BASE)/{0}" in '{1}'. Just do 'source "{0}"'
instead. The $srctree environment variable already points to the Zephyr root,
and all 'source's are relative to it.""".format(match.group(1), fname)
                )

    def check_redundant_document_separator(self, fname):
        # Looks for redundant '...' document separators in bindings

        with open(GIT_TOP / fname, encoding="utf-8") as f:
            if re.search(r"^\.\.\.", f.read(), re.MULTILINE):
                self.failure(f"""\
Redundant '...' document separator in {fname}. Binding YAML files are never
concatenated together, so no document separators are needed.""")

    def check_source_file(self, fname):
        # Generic nits related to various source files

        with open(GIT_TOP / fname, encoding="utf-8") as f:
            contents = f.read()

        if not contents.endswith("\n"):
            self.failure(f"Missing newline at end of '{fname}'. Check your text editor settings.")

        if contents.startswith("\n"):
            self.failure(f"Please remove blank lines at start of '{fname}'")

        if contents.endswith("\n\n"):
            self.failure(f"Please remove blank lines at end of '{fname}'")


class GitDiffCheck(ComplianceTest):
    """
    Checks for conflict markers or whitespace errors with git diff --check
    """

    name = "GitDiffCheck"
    doc = "Git conflict markers and whitespace errors are not allowed in added changes"

    def run(self):
        offending_lines = []
        # Use regex to filter out unnecessay output
        # Reason: `--check` is mutually exclusive with `--name-only` and `-s`
        p = re.compile(r"\S+\: .*\.")

        for shaidx in get_shas(COMMIT_RANGE):
            # Ignore non-zero return status code
            # Reason: `git diff --check` sets the return code to the number of offending lines
            cmd = ["diff", f"{shaidx}^!", "--check", "--", ":!*.diff", ":!*.patch"]
            diff = git(*cmd, ignore_non_zero=True)

            lines = p.findall(diff)
            lines = map(lambda x: f"{shaidx}: {x}", lines)
            offending_lines.extend(lines)

        if len(offending_lines) > 0:
            self.failure("\n".join(offending_lines))


class LicenseAndCopyrightCheck(ComplianceTest):
    """
    Verify that every file touched by the patch set has correct SPDX headers and uses allowed
    license.
    """

    name = "LicenseAndCopyrightCheck"
    doc = "Check SPDX headers and copyright lines with the reuse Python API."

    def _report_violations(
        self,
        paths: Iterable[Path],
        title: str,
        severity: str,
        desc: str | None = None,
    ) -> None:
        for p in paths:
            rel_path = os.path.relpath(str(p), GIT_TOP)
            self.fmtd_failure(severity, title, rel_path, desc=desc or "", line=1)

    def run(self) -> None:
        changed_files = get_files(filter="d")
        if not changed_files:
            return

        # Only scan text files for now, in the future we may want to leverage REUSE standard's
        # ability to also associate license/copyright info with binary files.
        for file in changed_files:
            full_path = GIT_TOP / file
            mime_type = magic.from_file(os.fspath(full_path), mime=True)
            if not mime_type.startswith("text/"):
                changed_files.remove(file)

        project = Project.from_directory(GIT_TOP)
        report = ProjectSubsetReport.generate(project, changed_files, multiprocessing=False)

        self._report_violations(
            report.files_without_licenses,
            "License missing",
            "warning",
            "File has no SPDX-License-Identifier header, consider adding one.",
        )

        self._report_violations(
            report.files_without_copyright,
            "Copyright missing",
            "warning",
            "File has no SPDX-FileCopyrightText header, consider adding one.",
        )

        for lic_id, paths in getattr(report, "missing_licenses", {}).items():
            self._report_violations(
                paths,
                "License may not be allowed",
                "warning",
                (
                    f"License file for '{lic_id}' not found in /LICENSES. Please check "
                    "https://docs.zephyrproject.org/latest/contribute/guidelines.html#components-using-other-licenses."
                ),
            )


class GitLint(ComplianceTest):
    """
    Runs gitlint on the commits and finds issues with style and syntax

    """

    name = "Gitlint"
    doc = zephyr_doc_detail_builder("/contribute/guidelines.html#commit-guidelines")

    def run(self):
        # By default gitlint looks for .gitlint configuration only in
        # the current directory
        try:
            subprocess.run(
                'gitlint --commits ' + COMMIT_RANGE,
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                shell=True,
                cwd=GIT_TOP,
            )

        except subprocess.CalledProcessError as ex:
            self.failure(ex.output.decode("utf-8"))


class PyLint(ComplianceTest):
    """
    Runs pylint on all .py files, with a limited set of checks enabled. The
    configuration is in the pylintrc file.
    """

    name = "Pylint"
    doc = "See https://www.pylint.org/ for more details"

    def run(self):
        # Path to pylint configuration file
        pylintrc = os.path.abspath(os.path.join(os.path.dirname(__file__), "pylintrc"))

        # Path to additional pylint check scripts
        check_script_dir = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "../pylint/checkers")
        )

        # List of files added/modified by the commit(s).
        files = get_files(filter="d")

        # Filter out everything but Python files. Keep filenames
        # relative (to GIT_TOP) to stay farther from any command line
        # limit.
        py_files = filter_py(GIT_TOP, files)
        if not py_files:
            return

        python_environment = os.environ.copy()
        if "PYTHONPATH" in python_environment:
            python_environment["PYTHONPATH"] = (
                check_script_dir + ":" + python_environment["PYTHONPATH"]
            )
        else:
            python_environment["PYTHONPATH"] = check_script_dir

        pylintcmd = [
            "pylint",
            "--output-format=json2",
            "--rcfile=" + pylintrc,
            "--load-plugins=argparse-checker",
        ] + py_files
        logger.info(cmd2str(pylintcmd))
        try:
            subprocess.run(
                pylintcmd,
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                cwd=GIT_TOP,
                env=python_environment,
            )
        except subprocess.CalledProcessError as ex:
            output = ex.output.decode("utf-8")
            messages = json.loads(output)['messages']
            for m in messages:
                severity = 'unknown'
                if m['messageId'][0] in ('F', 'E'):
                    severity = 'error'
                elif m['messageId'][0] in ('W', 'C', 'R', 'I'):
                    severity = 'warning'
                self.fmtd_failure(
                    severity,
                    m['messageId'],
                    m['path'],
                    m['line'],
                    col=str(m['column']),
                    desc=m['message'] + f" ({m['symbol']})",
                )

            if len(messages) == 0:
                # If there are no specific messages add the whole output as a failure
                self.failure(output)


def filter_py(root, fnames):
    # PyLint check helper. Returns all Python script filenames among the
    # filenames in 'fnames', relative to directory 'root'.
    #
    # Uses the python-magic library, so that we can detect Python
    # files that don't end in .py as well. python-magic is a frontend
    # to libmagic, which is also used by 'file'.
    return [
        fname
        for fname in fnames
        if (
            fname.endswith(".py")
            or magic.from_file(os.path.join(root, fname), mime=True) == "text/x-python"
        )
    ]


class CMakeStyle(ComplianceTest):
    """
    Checks cmake style added/modified files
    """

    name = "CMakeStyle"
    doc = zephyr_doc_detail_builder("/contribute/style/cmake.html")

    def run(self):
        # Loop through added/modified files
        for fname in get_files(filter="d"):
            if fname.endswith(".cmake") or fname.endswith("CMakeLists.txt"):
                self.check_style(fname)

    def check_style(self, fname):
        SPACE_BEFORE_OPEN_BRACKETS_CHECK = re.compile(r"^\s*if\s+\(")
        TAB_INDENTATION_CHECK = re.compile(r"^\t+")

        with open(fname, encoding="utf-8") as f:
            for line_num, line in enumerate(f.readlines(), start=1):
                if TAB_INDENTATION_CHECK.match(line):
                    self.fmtd_failure(
                        "error",
                        "CMakeStyle",
                        fname,
                        line_num,
                        "Use spaces instead of tabs for indentation",
                    )

                if SPACE_BEFORE_OPEN_BRACKETS_CHECK.match(line):
                    self.fmtd_failure(
                        "error",
                        "CMakeStyle",
                        fname,
                        line_num,
                        "Remove space before '(' in if() statements",
                    )


class Identity(ComplianceTest):
    """
    Checks if Emails of author and signed-off messages are consistent.
    """

    name = "Identity"
    doc = zephyr_doc_detail_builder("/contribute/guidelines.html#commit-guidelines")

    def run(self):
        for shaidx in get_shas(COMMIT_RANGE):
            commit_info = git('show', '-s', '--format=%an%n%ae%n%b', shaidx).split('\n', 2)

            failures = []

            if len(commit_info) == 2:
                failures.append(f'{shaidx}: Empty commit message body')
                auth_name, auth_email = commit_info
                body = ''
            elif len(commit_info) == 3:
                auth_name, auth_email, body = commit_info
            else:
                self.failure(f'Unable to parse commit message for {shaidx}')
                continue

            if auth_email.endswith("@users.noreply.github.com"):
                failures.append(
                    f"{shaidx}: author email ({auth_email}) must "
                    "be a real email and cannot end in "
                    "@users.noreply.github.com"
                )

            # Returns an array of everything to the right of ':' on each signoff line
            signoff_lines = re.findall(r"signed-off-by:\s(.*)", body, re.IGNORECASE)
            if len(signoff_lines) == 0:
                failures.append(f'{shaidx}: Missing signed-off-by line')
            else:
                # Validate all signoff lines' syntax while also searching for commit author
                found_author_signoff = False
                for signoff in signoff_lines:
                    match = re.search(r"(.+) <(.+)>", signoff)

                    if not match:
                        failures.append(
                            f"{shaidx}: Signed-off-by line ({signoff}) "
                            "does not follow the syntax: First "
                            "Last <email>."
                        )
                    elif (auth_name, auth_email) == match.groups():
                        found_author_signoff = True

                if not found_author_signoff:
                    failures.append(
                        f"{shaidx}: author name ({auth_name}) and email ({auth_email}) "
                        "needs to match one of the signed-off-by entries."
                    )

            if failures:
                self.failure('\n'.join(failures))


class BinaryFiles(ComplianceTest):
    """
    Check that the diff contains no binary files.
    """

    name = "BinaryFiles"
    doc = "No binary files allowed."

    def run(self):
        BINARY_ALLOW_PATHS = ("doc/", "boards/", "samples/")
        # svg files are always detected as binary, see .gitattributes
        BINARY_ALLOW_EXT = (".jpg", ".jpeg", ".png", ".svg", ".webp")

        for stat in git("diff", "--numstat", "--diff-filter=A", COMMIT_RANGE).splitlines():
            added, deleted, fname = stat.split("\t")
            if added == "-" and deleted == "-":
                if fname.startswith(BINARY_ALLOW_PATHS) and fname.endswith(BINARY_ALLOW_EXT):
                    continue
                self.failure(f"Binary file not allowed: {fname}")


class ImageSize(ComplianceTest):
    """
    Check that any added image is limited in size.
    """

    name = "ImageSize"
    doc = "Check the size of image files."

    def run(self):
        SIZE_LIMIT = 250 << 10
        BOARD_SIZE_LIMIT = 100 << 10

        for file in get_files(filter="d"):
            full_path = GIT_TOP / file
            mime_type = magic.from_file(os.fspath(full_path), mime=True)

            if not mime_type.startswith("image/"):
                continue

            size = os.path.getsize(full_path)

            limit = SIZE_LIMIT
            if file.startswith("boards/"):
                limit = BOARD_SIZE_LIMIT

            if size > limit:
                self.failure(
                    f"Image file too large: {file} reduce size to less than {limit >> 10}kB"
                )


class MaintainersFormat(ComplianceTest):
    """
    Check that MAINTAINERS file parses correctly.
    """

    name = "MaintainersFormat"
    doc = "Check that MAINTAINERS file parses correctly."

    def run(self):
        MAINTAINERS_FILES = ["MAINTAINERS.yml", "MAINTAINERS.yaml"]

        for file in MAINTAINERS_FILES:
            if not os.path.exists(file):
                continue

            try:
                Maintainers(file)
            except MaintainersError as ex:
                self.failure(f"Error parsing {file}: {ex}")


class ModulesMaintainers(ComplianceTest):
    """
    Check that all modules have a MAINTAINERS entry.
    """

    name = "ModulesMaintainers"
    doc = "Check that all modules have a MAINTAINERS entry."

    def run(self):
        MAINTAINERS_FILES = ["MAINTAINERS.yml", "MAINTAINERS.yaml"]

        manifest = Manifest.from_file()

        maintainers_file = None
        for file in MAINTAINERS_FILES:
            if os.path.exists(file):
                maintainers_file = file
                break
        if not maintainers_file:
            return

        maintainers = Maintainers(maintainers_file)

        for project in manifest.get_projects([]):
            if not manifest.is_active(project):
                continue

            if isinstance(project, ManifestProject):
                continue

            area = f"West project: {project.name}"
            if area not in maintainers.areas:
                self.failure(f"Missing {maintainers_file} entry for: \"{area}\"")


class ZephyrModuleFile(ComplianceTest):
    """
    Check that no zephyr/module.yml file has been added to the Zephyr repository
    """

    name = "ZephyrModuleFile"
    doc = "Check that no zephyr/module.yml file has been added to the Zephyr repository."

    def run(self):
        module_files = [
            ZEPHYR_BASE / 'zephyr' / 'module.yml',
            ZEPHYR_BASE / 'zephyr' / 'module.yaml',
        ]

        for file in module_files:
            if os.path.exists(file):
                self.failure("A zephyr module file has been added to the Zephyr repository")
                break


class YAMLLint(ComplianceTest):
    """
    YAMLLint
    """

    name = "YAMLLint"
    doc = "Check YAML files with YAMLLint."

    def run(self):
        config_file = ZEPHYR_BASE / ".yamllint"

        for file in get_files(filter="d"):
            if Path(file).suffix not in ['.yaml', '.yml']:
                continue

            yaml_config = config.YamlLintConfig(file=config_file)

            if file.startswith(".github/"):
                # Tweak few rules for workflow files.
                yaml_config.rules["line-length"] = False
                yaml_config.rules["truthy"]["allowed-values"].extend(['on', 'off'])
            elif file == ".codecov.yml":
                yaml_config.rules["truthy"]["allowed-values"].extend(['yes', 'no'])

            with open(file) as fp:
                for p in linter.run(fp, yaml_config):
                    self.fmtd_failure(
                        'warning', f'YAMLLint ({p.rule})', file, p.line, col=p.column, desc=p.desc
                    )


class SphinxLint(ComplianceTest):
    """
    SphinxLint
    """

    name = "SphinxLint"
    doc = "Check Sphinx/reStructuredText files with sphinx-lint."

    # Checkers added/removed to sphinx-lint's default set
    DISABLE_CHECKERS = [
        "horizontal-tab",
        "missing-space-before-default-role",
        "trailing-whitespace",
    ]
    ENABLE_CHECKERS = ["default-role"]

    def run(self):
        for file in get_files():
            if not file.endswith(".rst"):
                continue

            try:
                # sphinx-lint does not expose a public API so interaction is done via CLI
                disable_checkers = ','.join(self.DISABLE_CHECKERS)
                enable_checkers = ','.join(self.ENABLE_CHECKERS)
                subprocess.run(
                    f"sphinx-lint -d {disable_checkers} -e {enable_checkers} {file}",
                    check=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    shell=True,
                    cwd=GIT_TOP,
                )

            except subprocess.CalledProcessError as ex:
                for line in ex.output.decode("utf-8").splitlines():
                    match = re.match(r"^(.*):(\d+): (.*)$", line)

                    if match:
                        self.fmtd_failure(
                            "error",
                            "SphinxLint",
                            match.group(1),
                            int(match.group(2)),
                            desc=match.group(3),
                        )


class KeepSorted(ComplianceTest):
    """
    Check for blocks of code or config that should be kept sorted.
    """

    name = "KeepSorted"
    doc = "Check for blocks of code or config that should be kept sorted."

    MARKER = "zephyr-keep-sorted"

    def block_check_sorted(self, block_data, *, regex, strip, fold):
        def _test_indent(txt: str):
            return txt.startswith((" ", "\t"))

        if regex is None:
            block_data = textwrap.dedent(block_data)

        lines = block_data.splitlines()
        last = ''

        for idx, line in enumerate(lines):
            if not line.strip():
                # Ignore blank lines
                continue

            if strip is not None:
                line = line.strip(strip)

            if regex:
                # check for regex
                if not re.match(regex, line):
                    continue
            else:
                if _test_indent(line):
                    continue

                if fold:
                    # Fold back indented lines after the current one
                    for cont in takewhile(_test_indent, lines[idx + 1 :]):
                        line += cont.strip()

            if line < last:
                return idx

            last = line

        return -1

    def check_file(self, file, fp):
        mime_type = magic.from_file(os.fspath(file), mime=True)

        if not mime_type.startswith("text/"):
            return

        block_data = ""
        in_block = False

        start_marker = f"{self.MARKER}-start"
        stop_marker = f"{self.MARKER}-stop"
        regex_marker = r"re\(([^)]+)\)"
        strip_marker = r"strip\(([^)]+)\)"
        nofold_marker = "nofold"
        start_line = 0
        regex = None
        strip = None
        fold = True

        for line_num, line in enumerate(fp.readlines(), start=1):
            if start_marker in line:
                if in_block:
                    desc = f"nested {start_marker}"
                    self.fmtd_failure("error", "KeepSorted", file, line_num, desc=desc)
                in_block = True
                block_data = ""
                start_line = line_num + 1

                # Test for a regex block
                match = re.search(regex_marker, line)
                regex = match.group(1) if match else None

                match = re.search(strip_marker, line)
                strip = match.group(1) if match else None

                fold = nofold_marker not in line
            elif stop_marker in line:
                if not in_block:
                    desc = f"{stop_marker} without {start_marker}"
                    self.fmtd_failure("error", "KeepSorted", file, line_num, desc=desc)
                in_block = False

                idx = self.block_check_sorted(block_data, regex=regex, strip=strip, fold=fold)
                if idx >= 0:
                    desc = f"sorted block has out-of-order line at {start_line + idx}"
                    self.fmtd_failure("error", "KeepSorted", file, line_num, desc=desc)
            elif in_block:
                block_data += line

        if in_block:
            self.failure(f"unterminated {start_marker} in {file}")

    def run(self):
        for file in get_files(filter="d"):
            with open(file) as fp:
                self.check_file(file, fp)


class Ruff(ComplianceTest):
    """
    Ruff
    """

    name = "Ruff"
    doc = "Check python files with ruff."

    def run(self):
        try:
            subprocess.run(
                "ruff check --output-format=json",
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.DEVNULL,
                shell=True,
                cwd=GIT_TOP,
            )
        except subprocess.CalledProcessError as ex:
            output = ex.output.decode("utf-8")
            messages = json.loads(output)
            for m in messages:
                self.fmtd_failure(
                    "error",
                    f'Python lint error ({m.get("code")}) see {m.get("url")}',
                    m.get("filename"),
                    line=m.get("location", {}).get("row"),
                    col=m.get("location", {}).get("column"),
                    end_line=m.get("end_location", {}).get("row"),
                    end_col=m.get("end_location", {}).get("column"),
                    desc=m.get("message"),
                )

        for file in get_files(filter="d"):
            if not file.endswith((".py", ".pyi")):
                continue

            try:
                subprocess.run(
                    f"ruff format --force-exclude --diff {file}",
                    check=True,
                    shell=True,
                    cwd=GIT_TOP,
                )
            except subprocess.CalledProcessError:
                desc = f"Run 'ruff format {file}'"
                self.fmtd_failure("error", "Python format error", file, desc=desc)


class PythonCompatCheck(ComplianceTest):
    """
    Python Compatibility Check
    """

    name = "PythonCompat"
    doc = "Check that Python files are compatible with Zephyr minimum supported Python version."

    MAX_VERSION = (3, 10)
    MAX_VERSION_STR = f"{MAX_VERSION[0]}.{MAX_VERSION[1]}"

    def run(self):
        py_files = [f for f in get_files(filter="d") if f.endswith(".py")]
        if not py_files:
            return
        cmd = [
            "vermin",
            "-f",
            "parsable",
            "--violations",
            f"-t={self.MAX_VERSION_STR}",
            "--no-make-paths-absolute",
        ] + py_files
        try:
            result = subprocess.run(cmd, check=False, capture_output=True, cwd=GIT_TOP)
        except Exception as ex:
            self.error(f"Failed to run vermin: {ex}")
        output = result.stdout.decode("utf-8")
        failed = False
        for line in output.splitlines():
            parts = line.split(":")
            if len(parts) < 6:
                continue
            filename, line_number, column, _, py3ver, feature = parts[:6]
            if not line_number:
                # Ignore all file-level messages
                continue

            desc = None
            if py3ver.startswith('!'):
                desc = f"{feature} is known to be incompatible with Python 3."
            elif py3ver.startswith('~'):
                # "no known reason it won't work", just skip
                continue
            else:
                major, minor = map(int, py3ver.split(".")[:2])
                if (major, minor) > self.MAX_VERSION:
                    desc = (
                        f"{feature} requires Python {major}.{minor}, which is higher than "
                        f"Zephyr's minimum supported Python version ({self.MAX_VERSION_STR})."
                    )

            if desc is not None:
                self.fmtd_failure(
                    "error",
                    "PythonCompat",
                    filename,
                    line=int(line_number),
                    col=int(column) if column else None,
                    desc=desc,
                )
                failed = True
        if failed:
            self.failure(
                "Some Python files use features that are not compatible with Python "
                f"{self.MAX_VERSION_STR}."
            )


class TextEncoding(ComplianceTest):
    """
    Check that any text file is encoded in ascii or utf-8.
    """

    name = "TextEncoding"
    doc = "Check the encoding of text files."

    ALLOWED_CHARSETS = ["us-ascii", "utf-8"]

    def run(self):
        m = magic.Magic(mime=True, mime_encoding=True)

        for file in get_files(filter="d"):
            full_path = GIT_TOP / file
            mime_type = m.from_file(os.fspath(full_path))

            if not mime_type.startswith("text/"):
                continue

            # format is "text/<type>; charset=<charset>"
            if mime_type.rsplit('=')[-1] not in self.ALLOWED_CHARSETS:
                desc = f"Text file with unsupported encoding: {file} has mime type {mime_type}"
                self.fmtd_failure("error", "TextEncoding", file, desc=desc)


def init_logs(cli_arg):
    # Initializes logging

    global logger

    level = os.environ.get('LOG_LEVEL', "WARN")

    console = logging.StreamHandler()
    console.setFormatter(logging.Formatter('%(levelname)-8s: %(message)s'))

    logger = logging.getLogger('')
    logger.addHandler(console)
    logger.setLevel(cli_arg or level)

    logger.info("Log init completed, level=%s", logging.getLevelName(logger.getEffectiveLevel()))


def inheritors(klass):
    subclasses = set()
    work = [klass]
    while work:
        parent = work.pop()
        for child in parent.__subclasses__():
            if child not in subclasses:
                subclasses.add(child)
                work.append(child)
    return subclasses


def annotate(res):
    """
    https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#about-workflow-commands
    """
    msg = res.message.replace('%', '%25').replace('\n', '%0A').replace('\r', '%0D')
    notice = (
        f'::{res.severity} file={res.file}'
        + (f',line={res.line}' if res.line else '')
        + (f',col={res.col}' if res.col else '')
        + (f',endLine={res.end_line}' if res.end_line else '')
        + (f',endColumn={res.end_col}' if res.end_col else '')
        + f',title={res.title}::{msg}'
    )
    print(notice)


def resolve_path_hint(hint):
    if hint == "<zephyr-base>":
        return ZEPHYR_BASE
    elif hint == "<git-top>":
        return GIT_TOP
    else:
        return hint


def parse_args(argv):
    default_range = 'HEAD~1..HEAD'
    parser = argparse.ArgumentParser(
        description="Check for coding style and documentation warnings.", allow_abbrev=False
    )
    parser.add_argument(
        '-c',
        '--commits',
        default=default_range,
        help=f'''Commit range in the form: a..[b], default is
                        {default_range}''',
    )
    parser.add_argument(
        '-o',
        '--output',
        default="compliance.xml",
        help='''Name of outfile in JUnit format,
                        default is ./compliance.xml''',
    )
    parser.add_argument(
        '-n',
        '--no-case-output',
        action="store_true",
        help="Do not store the individual test case output.",
    )
    parser.add_argument('-l', '--list', action="store_true", help="List all checks and exit")
    parser.add_argument(
        "-v",
        "--loglevel",
        choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
        help="python logging level",
    )
    parser.add_argument(
        '-m',
        '--module',
        action="append",
        default=[],
        help="Checks to run. All checks by default. (case insensitive)",
    )
    parser.add_argument(
        '-e',
        '--exclude-module',
        action="append",
        default=[],
        help="Do not run the specified checks (case insensitive)",
    )
    parser.add_argument(
        '-j',
        '--previous-run',
        default=None,
        help='''Pre-load JUnit results in XML format
                        from a previous run and combine with new results.''',
    )
    parser.add_argument(
        '--annotate', action="store_true", help="Print GitHub Actions-compatible annotations."
    )

    return parser.parse_args(argv)


def _main(args):
    # The "real" main(), which is wrapped to catch exceptions and report them
    # to GitHub. Returns the number of test failures.

    # The absolute path of the top-level git directory. Initialize it here so
    # that issues running Git can be reported to GitHub.
    global GIT_TOP
    GIT_TOP = Path(git("rev-parse", "--show-toplevel"))

    # The commit range passed in --commit, e.g. "HEAD~3"
    global COMMIT_RANGE
    COMMIT_RANGE = args.commits

    init_logs(args.loglevel)

    logger.info(f'Running tests on commit range {COMMIT_RANGE}')

    if args.list:
        for testcase in sorted(inheritors(ComplianceTest), key=lambda x: x.name):
            print(testcase.name)
        return 0

    # Load saved test results from an earlier run, if requested
    if args.previous_run:
        if not os.path.exists(args.previous_run):
            # This probably means that an earlier pass had an internal error
            # (the script is currently run multiple times by the ci-pipelines
            # repo). Since that earlier pass might've posted an error to
            # GitHub, avoid generating a GitHub comment here, by avoiding
            # sys.exit() (which gets caught in main()).
            print(f"error: '{args.previous_run}' not found", file=sys.stderr)
            return 1

        logging.info(f"Loading previous results from {args.previous_run}")
        for loaded_suite in JUnitXml.fromfile(args.previous_run):
            suite = loaded_suite
            break
    else:
        suite = TestSuite("Compliance")

    included = list(map(lambda x: x.lower(), args.module))
    excluded = list(map(lambda x: x.lower(), args.exclude_module))

    for testcase in inheritors(ComplianceTest):
        # "Modules" and "testcases" are the same thing. Better flags would have
        # been --tests and --exclude-tests or the like, but it's awkward to
        # change now.

        if included and testcase.name.lower() not in included:
            continue

        if testcase.name.lower() in excluded:
            print("Skipping " + testcase.name)
            continue

        test = testcase()
        try:
            print(f"Running {test.name:30} tests in {resolve_path_hint(test.path_hint)} ...")
            test.run()
        except EndTest:
            pass
        except BaseException:
            test.failure(f"An exception occurred in {test.name}:\n{traceback.format_exc()}")

        # Annotate if required
        if args.annotate:
            for res in test.fmtd_failures:
                annotate(res)

        suite.add_testcase(test.case)

    if args.output:
        xml = JUnitXml()
        xml.add_testsuite(suite)
        xml.update_statistics()
        xml.write(args.output, pretty=True)

    failed_cases = []
    warning_cases = []
    name2doc = {testcase.name: testcase.doc for testcase in inheritors(ComplianceTest)}

    for case in suite:
        if case.result:
            if case.is_skipped:
                logging.warning(f"Skipped {case.name}")
            else:
                if any(res.type in ('error', 'failure') for res in case.result):
                    failed_cases.append(case)
                else:
                    warning_cases.append(case)
        else:
            # Some checks can produce no .result
            logging.info(f"No JUnit result for {case.name}")

    n_fails = len(failed_cases)
    n_warnings = len(warning_cases)

    if n_fails or n_warnings:
        if n_fails:
            print(f"{n_fails} check(s) failed")
        if n_warnings:
            print(f"{n_warnings} check(s) with warnings only")

        for case in failed_cases + warning_cases:
            for res in case.result:
                errmsg = res.text.strip()
                if res.type in ('error', 'failure'):
                    logging.error(f"Test {case.name} failed: \n{errmsg}")
                else:
                    logging.warning(f"Test {case.name} warning: \n{errmsg}")

            if args.no_case_output:
                continue
            with open(f"{case.name}.txt", "w") as f:
                docs = name2doc.get(case.name)
                f.write(f"{docs}\n")
                for res in case.result:
                    errmsg = res.text.strip()
                    f.write(f'\n {errmsg}')

    if args.output:
        print(f"\nComplete results in {args.output}")
    return n_fails


def main(argv=None):
    args = parse_args(argv)

    try:
        n_fails = _main(args)
    except BaseException:
        # Catch BaseException instead of Exception to include stuff like
        # SystemExit (raised by sys.exit())
        print(f"Python exception in `{__file__}`:\n\n```\n{traceback.format_exc()}\n```")

        raise

    sys.exit(n_fails)


def cmd2str(cmd):
    # Formats the command-line arguments in the iterable 'cmd' into a string,
    # for error messages and the like

    return " ".join(shlex.quote(word) for word in cmd)


def err(msg):
    cmd = sys.argv[0]  # Empty if missing
    if cmd:
        cmd += ": "
    sys.exit(f"{cmd} error: {msg}")


if __name__ == "__main__":
    main(sys.argv[1:])
