# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2012 The Chromium OS Authors.
# Author: Simon Glass <sjg@chromium.org>
# Author: Masahiro Yamada <yamada.m@jp.panasonic.com>

"""Maintains a list of boards and allows them to be selected"""

from collections import OrderedDict
import errno
import fnmatch
import glob
import multiprocessing
import os
import re
import sys
import tempfile
import time

from buildman import board
from buildman import kconfiglib

from u_boot_pylib.terminal import print_clear, tprint

### constant variables ###
OUTPUT_FILE = 'boards.cfg'
CONFIG_DIR = 'configs'
SLEEP_TIME = 0.03
COMMENT_BLOCK = f'''#
# List of boards
#   Automatically generated by {__file__}: don't edit
#
# Status, Arch, CPU, SoC, Vendor, Board, Target, Config, Maintainers

'''


def try_remove(fname):
    """Remove a file ignoring 'No such file or directory' error.

    Args:
        fname (str): Filename to remove

    Raises:
        OSError: output file exists but could not be removed
    """
    try:
        os.remove(fname)
    except OSError as exception:
        # Ignore 'No such file or directory' error
        if exception.errno != errno.ENOENT:
            raise


def output_is_new(output, config_dir, srcdir):
    """Check if the output file is up to date.

    Looks at defconfig and Kconfig files to make sure none is newer than the
    output file. Also ensures that the boards.cfg does not mention any removed
    boards.

    Args:
        output (str): Filename to check
        config_dir (str): Directory containing defconfig files
        srcdir (str): Directory containing Kconfig and MAINTAINERS files

    Returns:
        True if the given output file exists and is newer than any of
        *_defconfig, MAINTAINERS and Kconfig*.  False otherwise.

    Raises:
        OSError: output file exists but could not be opened
    """
    # pylint: disable=too-many-branches
    try:
        ctime = os.path.getctime(output)
    except OSError as exception:
        if exception.errno == errno.ENOENT:
            # return False on 'No such file or directory' error
            return False
        raise

    for (dirpath, _, filenames) in os.walk(config_dir):
        for filename in fnmatch.filter(filenames, '*_defconfig'):
            if fnmatch.fnmatch(filename, '.*'):
                continue
            filepath = os.path.join(dirpath, filename)
            if ctime < os.path.getctime(filepath):
                return False

    for (dirpath, _, filenames) in os.walk(srcdir):
        for filename in filenames:
            if (fnmatch.fnmatch(filename, '*~') or
                not fnmatch.fnmatch(filename, 'Kconfig*') and
                not filename == 'MAINTAINERS'):
                continue
            filepath = os.path.join(dirpath, filename)
            if ctime < os.path.getctime(filepath):
                return False

    # Detect a board that has been removed since the current board database
    # was generated
    with open(output, encoding="utf-8") as inf:
        for line in inf:
            if 'Options,' in line:
                return False
            if line[0] == '#' or line == '\n':
                continue
            defconfig = line.split()[6] + '_defconfig'
            if not os.path.exists(os.path.join(config_dir, defconfig)):
                return False

    return True


class Expr:
    """A single regular expression for matching boards to build"""

    def __init__(self, expr):
        """Set up a new Expr object.

        Args:
            expr (str): String containing regular expression to store
        """
        self._expr = expr
        self._re = re.compile(expr)

    def matches(self, props):
        """Check if any of the properties match the regular expression.

        Args:
           props (list of str): List of properties to check
        Returns:
           True if any of the properties match the regular expression
        """
        for prop in props:
            if self._re.match(prop):
                return True
        return False

    def __str__(self):
        return self._expr

class Term:
    """A list of expressions each of which must match with properties.

    This provides a list of 'AND' expressions, meaning that each must
    match the board properties for that board to be built.
    """
    def __init__(self):
        self._expr_list = []
        self._board_count = 0

    def add_expr(self, expr):
        """Add an Expr object to the list to check.

        Args:
            expr (Expr): New Expr object to add to the list of those that must
                  match for a board to be built.
        """
        self._expr_list.append(Expr(expr))

    def __str__(self):
        """Return some sort of useful string describing the term"""
        return '&'.join([str(expr) for expr in self._expr_list])

    def matches(self, props):
        """Check if any of the properties match this term

        Each of the expressions in the term is checked. All must match.

        Args:
           props (list of str): List of properties to check
        Returns:
           True if all of the expressions in the Term match, else False
        """
        for expr in self._expr_list:
            if not expr.matches(props):
                return False
        return True


class KconfigScanner:

    """Kconfig scanner."""

    ### constant variable only used in this class ###
    _SYMBOL_TABLE = {
        'arch' : 'SYS_ARCH',
        'cpu' : 'SYS_CPU',
        'soc' : 'SYS_SOC',
        'vendor' : 'SYS_VENDOR',
        'board' : 'SYS_BOARD',
        'config' : 'SYS_CONFIG_NAME',
        # 'target' is added later
    }

    def __init__(self, srctree):
        """Scan all the Kconfig files and create a Kconfig object."""
        # Define environment variables referenced from Kconfig
        os.environ['srctree'] = srctree
        os.environ['UBOOTVERSION'] = 'dummy'
        os.environ['KCONFIG_OBJDIR'] = ''
        self._tmpfile = None
        self._conf = kconfiglib.Kconfig(warn=False)

    def __del__(self):
        """Delete a leftover temporary file before exit.

        The scan() method of this class creates a temporay file and deletes
        it on success.  If scan() method throws an exception on the way,
        the temporary file might be left over.  In that case, it should be
        deleted in this destructor.
        """
        if self._tmpfile:
            try_remove(self._tmpfile)

    def scan(self, defconfig, warn_targets):
        """Load a defconfig file to obtain board parameters.

        Args:
            defconfig (str): path to the defconfig file to be processed
            warn_targets (bool): True to warn about missing or duplicate
                CONFIG_TARGET options

        Returns:
            tuple: dictionary of board parameters.  It has a form of:
                {
                    'arch': <arch_name>,
                    'cpu': <cpu_name>,
                    'soc': <soc_name>,
                    'vendor': <vendor_name>,
                    'board': <board_name>,
                    'target': <target_name>,
                    'config': <config_header_name>,
                }
            warnings (list of str): list of warnings found
        """
        leaf = os.path.basename(defconfig)
        expect_target, match, rear = leaf.partition('_defconfig')
        assert match and not rear, f'{leaf} : invalid defconfig'

        self._conf.load_config(defconfig)
        self._tmpfile = None

        params = {}
        warnings = []

        # Get the value of CONFIG_SYS_ARCH, CONFIG_SYS_CPU, ... etc.
        # Set '-' if the value is empty.
        for key, symbol in list(self._SYMBOL_TABLE.items()):
            value = self._conf.syms.get(symbol).str_value
            if value:
                params[key] = value
            else:
                params[key] = '-'

        # Check there is exactly one TARGET_xxx set
        if warn_targets:
            target = None
            for name, sym in self._conf.syms.items():
                if name.startswith('TARGET_') and sym.str_value == 'y':
                    tname = name[7:].lower()
                    if target:
                        warnings.append(
                            f'WARNING: {leaf}: Duplicate TARGET_xxx: {target} and {tname}')
                    else:
                        target = tname

            if not target:
                cfg_name = expect_target.replace('-', '_').upper()
                warnings.append(f'WARNING: {leaf}: No TARGET_{cfg_name} enabled')

        params['target'] = expect_target

        # fix-up for aarch64
        if params['arch'] == 'arm' and params['cpu'] == 'armv8':
            params['arch'] = 'aarch64'

        # fix-up for riscv
        if params['arch'] == 'riscv':
            try:
                value = self._conf.syms.get('ARCH_RV32I').str_value
            except:
                value = ''
            if value == 'y':
                params['arch'] = 'riscv32'
            else:
                params['arch'] = 'riscv64'

        return params, warnings


class MaintainersDatabase:

    """The database of board status and maintainers.

    Properties:
        database: dict:
            key: Board-target name (e.g. 'snow')
            value: tuple:
                str: Board status (e.g. 'Active')
                str: List of maintainers, separated by :
        warnings (list of str): List of warnings due to missing status, etc.
    """

    def __init__(self):
        """Create an empty database."""
        self.database = {}
        self.warnings = []

    def get_status(self, target):
        """Return the status of the given board.

        The board status is generally either 'Active' or 'Orphan'.
        Display a warning message and return '-' if status information
        is not found.

        Args:
            target (str): Build-target name

        Returns:
            str: 'Active', 'Orphan' or '-'.
        """
        if not target in self.database:
            self.warnings.append(f"WARNING: no status info for '{target}'")
            return '-'

        tmp = self.database[target][0]
        if tmp.startswith('Maintained'):
            return 'Active'
        if tmp.startswith('Supported'):
            return 'Active'
        if tmp.startswith('Orphan'):
            return 'Orphan'
        self.warnings.append(f"WARNING: {tmp}: unknown status for '{target}'")
        return '-'

    def get_maintainers(self, target):
        """Return the maintainers of the given board.

        Args:
            target (str): Build-target name

        Returns:
            str: Maintainers of the board.  If the board has two or more
            maintainers, they are separated with colons.
        """
        entry = self.database.get(target)
        if entry:
            status, maint_list = entry
            if not status.startswith('Orphan'):
                if len(maint_list) > 1 or (maint_list and maint_list[0] != '-'):
                    return ':'.join(maint_list)

        self.warnings.append(f"WARNING: no maintainers for '{target}'")
        return ''

    def parse_file(self, srcdir, fname):
        """Parse a MAINTAINERS file.

        Parse a MAINTAINERS file and accumulate board status and maintainers
        information in the self.database dict.

        defconfig files are used to specify the target, e.g. xxx_defconfig is
        used for target 'xxx'. If there is no defconfig file mentioned in the
        MAINTAINERS file F: entries, then this function does nothing.

        The N: name entries can be used to specify a defconfig file using
        wildcards.

        Args:
            srcdir (str): Directory containing source code (Kconfig files)
            fname (str): MAINTAINERS file to be parsed
        """
        def add_targets(linenum):
            """Add any new targets

            Args:
                linenum (int): Current line number
            """
            if targets:
                for target in targets:
                    self.database[target] = (status, maintainers)

        targets = []
        maintainers = []
        status = '-'
        with open(fname, encoding="utf-8") as inf:
            for linenum, line in enumerate(inf):
                # Check also commented maintainers
                if line[:3] == '#M:':
                    line = line[1:]
                tag, rest = line[:2], line[2:].strip()
                if tag == 'M:':
                    maintainers.append(rest)
                elif tag == 'F:':
                    # expand wildcard and filter by 'configs/*_defconfig'
                    glob_path = os.path.join(srcdir, rest)
                    for item in glob.glob(glob_path):
                        front, match, rear = item.partition('configs/')
                        if front.endswith('/'):
                            front = front[:-1]
                        if front == srcdir and match:
                            front, match, rear = rear.rpartition('_defconfig')
                            if match and not rear:
                                targets.append(front)
                elif tag == 'S:':
                    status = rest
                elif tag == 'N:':
                    # Just scan the configs directory since that's all we care
                    # about
                    walk_path = os.walk(os.path.join(srcdir, 'configs'))
                    for dirpath, _, fnames in walk_path:
                        for cfg in fnames:
                            path = os.path.join(dirpath, cfg)[len(srcdir) + 1:]
                            front, match, rear = path.partition('configs/')
                            if front or not match:
                                continue
                            front, match, rear = rear.rpartition('_defconfig')

                            # Use this entry if it matches the defconfig file
                            # without the _defconfig suffix. For example
                            # 'am335x.*' matches am335x_guardian_defconfig
                            if match and not rear and re.search(rest, front):
                                targets.append(front)
                elif line == '\n':
                    add_targets(linenum)
                    targets = []
                    maintainers = []
                    status = '-'
        add_targets(linenum)


class Boards:
    """Manage a list of boards."""
    def __init__(self):
        self._boards = []

    def add_board(self, brd):
        """Add a new board to the list.

        The board's target member must not already exist in the board list.

        Args:
            brd (Board): board to add
        """
        self._boards.append(brd)

    def read_boards(self, fname):
        """Read a list of boards from a board file.

        Create a Board object for each and add it to our _boards list.

        Args:
            fname (str): Filename of boards.cfg file
        """
        with open(fname, 'r', encoding='utf-8') as inf:
            for line in inf:
                if line[0] == '#':
                    continue
                fields = line.split()
                if not fields:
                    continue
                for upto, field in enumerate(fields):
                    if field == '-':
                        fields[upto] = ''
                while len(fields) < 8:
                    fields.append('')
                if len(fields) > 8:
                    fields = fields[:8]

                brd = board.Board(*fields)
                self.add_board(brd)


    def get_list(self):
        """Return a list of available boards.

        Returns:
            List of Board objects
        """
        return self._boards

    def get_dict(self):
        """Build a dictionary containing all the boards.

        Returns:
            Dictionary:
                key is board.target
                value is board
        """
        board_dict = OrderedDict()
        for brd in self._boards:
            board_dict[brd.target] = brd
        return board_dict

    def get_selected_dict(self):
        """Return a dictionary containing the selected boards

        Returns:
            List of Board objects that are marked selected
        """
        board_dict = OrderedDict()
        for brd in self._boards:
            if brd.build_it:
                board_dict[brd.target] = brd
        return board_dict

    def get_selected(self):
        """Return a list of selected boards

        Returns:
            List of Board objects that are marked selected
        """
        return [brd for brd in self._boards if brd.build_it]

    def get_selected_names(self):
        """Return a list of selected boards

        Returns:
            List of board names that are marked selected
        """
        return [brd.target for brd in self._boards if brd.build_it]

    @classmethod
    def _build_terms(cls, args):
        """Convert command line arguments to a list of terms.

        This deals with parsing of the arguments. It handles the '&'
        operator, which joins several expressions into a single Term.

        For example:
            ['arm & freescale sandbox', 'tegra']

        will produce 3 Terms containing expressions as follows:
            arm, freescale
            sandbox
            tegra

        The first Term has two expressions, both of which must match for
        a board to be selected.

        Args:
            args (list of str): List of command line arguments

        Returns:
            list of Term: A list of Term objects
        """
        syms = []
        for arg in args:
            for word in arg.split():
                sym_build = []
                for term in word.split('&'):
                    if term:
                        sym_build.append(term)
                    sym_build.append('&')
                syms += sym_build[:-1]
        terms = []
        term = None
        oper = None
        for sym in syms:
            if sym == '&':
                oper = sym
            elif oper:
                term.add_expr(sym)
                oper = None
            else:
                if term:
                    terms.append(term)
                term = Term()
                term.add_expr(sym)
        if term:
            terms.append(term)
        return terms

    def select_boards(self, args, exclude=None, brds=None):
        """Mark boards selected based on args

        Normally either boards (an explicit list of boards) or args (a list of
        terms to match against) is used. It is possible to specify both, in
        which case they are additive.

        If brds and args are both empty, all boards are selected.

        Args:
            args (list of str): List of strings specifying boards to include,
                either named, or by their target, architecture, cpu, vendor or
                soc. If empty, all boards are selected.
            exclude (list of str): List of boards to exclude, regardless of
                'args', or None for none
            brds (list of Board): List of boards to build, or None/[] for all

        Returns:
            Tuple
                Dictionary which holds the list of boards which were selected
                    due to each argument, arranged by argument.
                List of errors found
        """
        def _check_board(brd):
            """Check whether to include or exclude a board

            Checks the various terms and decide whether to build it or not (the
            'build_it' variable).

            If it is built, add the board to the result[term] list so we know
            which term caused it to be built. Add it to result['all'] also.

            Keep a list of boards we found in 'found', so we can report boards
            which appear in self._boards but not in brds.

            Args:
                brd (Board): Board to check
            """
            matching_term = None
            build_it = False
            if terms:
                for term in terms:
                    if term.matches(brd.props):
                        matching_term = str(term)
                        build_it = True
                        break
            elif brds:
                if brd.target in brds:
                    build_it = True
                    found.append(brd.target)
            else:
                build_it = True

            # Check that it is not specifically excluded
            for expr in exclude_list:
                if expr.matches(brd.props):
                    build_it = False
                    break

            if build_it:
                brd.build_it = True
                if matching_term:
                    result[matching_term].append(brd.target)
                result['all'].append(brd.target)

        result = OrderedDict()
        warnings = []
        terms = self._build_terms(args)

        result['all'] = []
        for term in terms:
            result[str(term)] = []

        exclude_list = []
        if exclude:
            for expr in exclude:
                exclude_list.append(Expr(expr))

        found = []
        for brd in self._boards:
            _check_board(brd)

        if brds:
            remaining = set(brds) - set(found)
            if remaining:
                warnings.append(f"Boards not found: {', '.join(remaining)}\n")

        return result, warnings

    @classmethod
    def scan_defconfigs_for_multiprocess(cls, srcdir, queue, defconfigs,
                                         warn_targets):
        """Scan defconfig files and queue their board parameters

        This function is intended to be passed to multiprocessing.Process()
        constructor.

        Args:
            srcdir (str): Directory containing source code
            queue (multiprocessing.Queue): The resulting board parameters are
                written into this.
            defconfigs (sequence of str): A sequence of defconfig files to be
                scanned.
            warn_targets (bool): True to warn about missing or duplicate
                CONFIG_TARGET options
        """
        kconf_scanner = KconfigScanner(srcdir)
        for defconfig in defconfigs:
            queue.put(kconf_scanner.scan(defconfig, warn_targets))

    @classmethod
    def read_queues(cls, queues, params_list, warnings):
        """Read the queues and append the data to the paramers list

        Args:
            queues (list of multiprocessing.Queue): Queues to read
            params_list (list of dict): List to add params too
            warnings (set of str): Set to add warnings to
        """
        for que in queues:
            while not que.empty():
                params, warn = que.get()
                params_list.append(params)
                warnings.update(warn)

    def scan_defconfigs(self, config_dir, srcdir, jobs=1, warn_targets=False):
        """Collect board parameters for all defconfig files.

        This function invokes multiple processes for faster processing.

        Args:
            config_dir (str): Directory containing the defconfig files
            srcdir (str): Directory containing source code (Kconfig files)
            jobs (int): The number of jobs to run simultaneously
            warn_targets (bool): True to warn about missing or duplicate
                CONFIG_TARGET options

        Returns:
            tuple:
                list of dict: List of board parameters, each a dict:
                    key: 'arch', 'cpu', 'soc', 'vendor', 'board', 'target',
                        'config'
                    value: string value of the key
                list of str: List of warnings recorded
        """
        all_defconfigs = []
        for (dirpath, _, filenames) in os.walk(config_dir):
            for filename in fnmatch.filter(filenames, '*_defconfig'):
                if fnmatch.fnmatch(filename, '.*'):
                    continue
                all_defconfigs.append(os.path.join(dirpath, filename))

        total_boards = len(all_defconfigs)
        processes = []
        queues = []
        for i in range(jobs):
            defconfigs = all_defconfigs[total_boards * i // jobs :
                                        total_boards * (i + 1) // jobs]
            que = multiprocessing.Queue(maxsize=-1)
            proc = multiprocessing.Process(
                target=self.scan_defconfigs_for_multiprocess,
                args=(srcdir, que, defconfigs, warn_targets))
            proc.start()
            processes.append(proc)
            queues.append(que)

        # The resulting data should be accumulated to these lists
        params_list = []
        warnings = set()

        # Data in the queues should be retrieved preriodically.
        # Otherwise, the queues would become full and subprocesses would get stuck.
        while any(p.is_alive() for p in processes):
            self.read_queues(queues, params_list, warnings)
            # sleep for a while until the queues are filled
            time.sleep(SLEEP_TIME)

        # Joining subprocesses just in case
        # (All subprocesses should already have been finished)
        for proc in processes:
            proc.join()

        # retrieve leftover data
        self.read_queues(queues, params_list, warnings)

        return params_list, sorted(list(warnings))

    @classmethod
    def insert_maintainers_info(cls, srcdir, params_list):
        """Add Status and Maintainers information to the board parameters list.

        Args:
            params_list (list of dict): A list of the board parameters

        Returns:
            list of str: List of warnings collected due to missing status, etc.
        """
        database = MaintainersDatabase()
        for (dirpath, _, filenames) in os.walk(srcdir):
            if 'MAINTAINERS' in filenames and 'tools/buildman' not in dirpath:
                database.parse_file(srcdir,
                                    os.path.join(dirpath, 'MAINTAINERS'))

        for i, params in enumerate(params_list):
            target = params['target']
            maintainers = database.get_maintainers(target)
            params['maintainers'] = maintainers
            if maintainers:
                params['status'] = database.get_status(target)
            else:
                params['status'] = '-'
            params_list[i] = params
        return sorted(database.warnings)

    @classmethod
    def format_and_output(cls, params_list, output):
        """Write board parameters into a file.

        Columnate the board parameters, sort lines alphabetically,
        and then write them to a file.

        Args:
            params_list (list of dict): The list of board parameters
            output (str): The path to the output file
        """
        fields = ('status', 'arch', 'cpu', 'soc', 'vendor', 'board', 'target',
                  'config', 'maintainers')

        # First, decide the width of each column
        max_length = {f: 0 for f in fields}
        for params in params_list:
            for field in fields:
                max_length[field] = max(max_length[field], len(params[field]))

        output_lines = []
        for params in params_list:
            line = ''
            for field in fields:
                # insert two spaces between fields like column -t would
                line += '  ' + params[field].ljust(max_length[field])
            output_lines.append(line.strip())

        # ignore case when sorting
        output_lines.sort(key=str.lower)

        with open(output, 'w', encoding="utf-8") as outf:
            outf.write(COMMENT_BLOCK + '\n'.join(output_lines) + '\n')

    def build_board_list(self, config_dir=CONFIG_DIR, srcdir='.', jobs=1,
                         warn_targets=False):
        """Generate a board-database file

        This works by reading the Kconfig, then loading each board's defconfig
        in to get the setting for each option. In particular, CONFIG_TARGET_xxx
        is typically set by the defconfig, where xxx is the target to build.

        Args:
            config_dir (str): Directory containing the defconfig files
            srcdir (str): Directory containing source code (Kconfig files)
            jobs (int): The number of jobs to run simultaneously
            warn_targets (bool): True to warn about missing or duplicate
                CONFIG_TARGET options

        Returns:
            tuple:
                list of dict: List of board parameters, each a dict:
                    key: 'arch', 'cpu', 'soc', 'vendor', 'board', 'config',
                         'target'
                    value: string value of the key
                list of str: Warnings that came up
        """
        params_list, warnings = self.scan_defconfigs(config_dir, srcdir, jobs,
                                                     warn_targets)
        m_warnings = self.insert_maintainers_info(srcdir, params_list)
        return params_list, warnings + m_warnings

    def ensure_board_list(self, output, jobs=1, force=False, quiet=False):
        """Generate a board database file if needed.

        This is intended to check if Kconfig has changed since the boards.cfg
        files was generated.

        Args:
            output (str): The name of the output file
            jobs (int): The number of jobs to run simultaneously
            force (bool): Force to generate the output even if it is new
            quiet (bool): True to avoid printing a message if nothing needs doing

        Returns:
            bool: True if all is well, False if there were warnings
        """
        if not force:
            if not quiet:
                tprint('\rChecking for Kconfig changes...', newline=False)
            is_new = output_is_new(output, CONFIG_DIR, '.')
            print_clear()
            if is_new:
                if not quiet:
                    print(f'{output} is up to date. Nothing to do.')
                return True
        if not quiet:
            tprint('\rGenerating board list...', newline=False)
        params_list, warnings = self.build_board_list(CONFIG_DIR, '.', jobs)
        print_clear()
        for warn in warnings:
            print(warn, file=sys.stderr)
        self.format_and_output(params_list, output)
        return not warnings
