#!/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 ProjectReport, 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, 'r') 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

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 = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#coding-style for more details."

    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'):
                self.failure("Perl not installed - required for checkpatch.pl. Please install Perl or add to PATH.")
                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_prefixes |= get_vendor_prefixes(ZEPHYR_BASE / "dts" / "bindings" / "vendor-prefixes.txt", 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 = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#clang-format for more details."

    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:
                    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(l) for l 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}')


class DevicetreeBindingsCheck(ComplianceTest):
    """
    Checks if we are introducing any unwanted properties in Devicetree Bindings.
    """
    name = "DevicetreeBindings"
    doc = "See https://docs.zephyrproject.org/latest/build/dts/bindings.html for more details."

    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 KconfigCheck(ComplianceTest):
    """
    Checks is we are introducing any new warnings/errors with Kconfig,
    for example using undefined Kconfig variables.
    """
    name = "Kconfig"
    doc = "See https://docs.zephyrproject.org/latest/build/kconfig/tips.html for more details."

    # 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, 'r') 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)

        # 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
        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_",
        "APP_LOG_LEVEL", # Application log level is not detected correctly as
                         # the option is defined using a template, so it can't
                         # be grepped
        "APP_LOG_LEVEL_DBG",
        "ARMCLANG_STD_LIBC",  # The ARMCLANG_STD_LIBC is defined in the
                              # toolchain Kconfig which is sourced based on
                              # Zephyr toolchain variant and therefore not
                              # visible to compliance.
        "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
        "BOOT_UPGRADE_ONLY", # Used in example adjusting MCUboot config, but
                             # symbol is defined in MCUboot itself.
        "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",
        "GEN_UICR_GENERATE_PERIPHCONF", # Used in specialized build tool, not part of main Kconfig
        "GEN_UICR_PROTECTEDMEM", # Used in specialized build tool, not part of main Kconfig
        "GEN_UICR_PROTECTEDMEM_SIZE_BYTES", # Used in specialized build tool, not part of main Kconfig
        "GEN_UICR_SECONDARY", # Used in specialized build tool, not part of main Kconfig
        "GEN_UICR_SECONDARY_GENERATE_PERIPHCONF", # Used in specialized build tool, not part of main Kconfig
        "GEN_UICR_SECONDARY_PROCESSOR_VALUE", # Used in specialized build tool, not part of main Kconfig
        "GEN_UICR_SECURESTORAGE", # Used in specialized build tool, not part of main Kconfig
        "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",
        "IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS", # Used in ICMsg tests for intercompatibility
                                                      # with older versions of the ICMsg.
        "LIBGCC_RTLIB",
        "LLVM_USE_LD",   # Both LLVM_USE_* are in cmake/toolchain/llvm/Kconfig
        "LLVM_USE_LLD",  # which are only included if LLVM is selected but
                         # not other toolchains. Compliance check would complain,
                         # for example, if you are using GCC.
        "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
        "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", # Used in modules/hal_nxp/mcux/mcux-sdk-ng/device/device.cmake.
                            # It is a variable used by MCUX SDK CMake.
        "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_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",
        "TOOLCHAIN", # 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_ARCMWDT_SUPPORTS_THREAD_LOCAL_STORAGE", # The symbol is defined in the toolchain
                                                    # Kconfig which is sourced based on Zephyr
                                                    # toolchain variant and therefore not visible
                                                    # to compliance.
        "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
        # 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 = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#coding-style for more details."

    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 "
                         f"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
            diff = git("diff", f"{shaidx}^!", "--check", "--", ":!*.diff", ":!*.patch", 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 = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-guidelines for more details"

    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 = "See https://docs.zephyrproject.org/latest/contribute/style/cmake.html for more details."

    def run(self):
        # Loop through added/modified files
        for fname in get_files(filter="d"):
            if fname.endswith(".cmake") or fname == "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 = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-guidelines for more details"

    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 "
                             f"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, 'r') 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
                subprocess.run(
                    f"sphinx-lint -d {','.join(self.DISABLE_CHECKERS)} -e {','.join(self.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, "r") as fp:
                self.check_file(file, fp)


class Ruff(ComplianceTest):
    """
    Ruff
    """
    name = "Ruff"
    doc = "Check python files with ruff."

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

            try:
                subprocess.run(
                    f"ruff check --force-exclude --output-format=json {file}",
                    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")}',
                        file,
                        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"),
                    )
            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 "
                  f"{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"
              f"```\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:])
