#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0+

"""Build and query a Kconfig database for boards.

See doc/develop/qconfig.rst for documentation.

Author: Masahiro Yamada <yamada.masahiro@socionext.com>
Author: Simon Glass <sjg@chromium.org>
"""

from argparse import ArgumentParser
import collections
from contextlib import ExitStack
import doctest
import filecmp
import fnmatch
import glob
import multiprocessing
import os
import queue
import re
import shutil
import subprocess
import sys
import tempfile
import threading
import time
import unittest

from buildman import bsettings
from buildman import kconfiglib
from buildman import toolchain
from u_boot_pylib import terminal

SHOW_GNU_MAKE = 'scripts/show-gnu-make'
SLEEP_TIME=0.03

STATE_IDLE = 0
STATE_DEFCONFIG = 1
STATE_AUTOCONF = 2
STATE_SAVEDEFCONFIG = 3

AUTO_CONF_PATH = 'include/config/auto.conf'
CONFIG_DATABASE = 'qconfig.db'
FAILED_LIST = 'qconfig.failed'

CONFIG_LEN = len('CONFIG_')

SIZES = {
    'SZ_1':    0x00000001, 'SZ_2':    0x00000002,
    'SZ_4':    0x00000004, 'SZ_8':    0x00000008,
    'SZ_16':   0x00000010, 'SZ_32':   0x00000020,
    'SZ_64':   0x00000040, 'SZ_128':  0x00000080,
    'SZ_256':  0x00000100, 'SZ_512':  0x00000200,
    'SZ_1K':   0x00000400, 'SZ_2K':   0x00000800,
    'SZ_4K':   0x00001000, 'SZ_8K':   0x00002000,
    'SZ_16K':  0x00004000, 'SZ_32K':  0x00008000,
    'SZ_64K':  0x00010000, 'SZ_128K': 0x00020000,
    'SZ_256K': 0x00040000, 'SZ_512K': 0x00080000,
    'SZ_1M':   0x00100000, 'SZ_2M':   0x00200000,
    'SZ_4M':   0x00400000, 'SZ_8M':   0x00800000,
    'SZ_16M':  0x01000000, 'SZ_32M':  0x02000000,
    'SZ_64M':  0x04000000, 'SZ_128M': 0x08000000,
    'SZ_256M': 0x10000000, 'SZ_512M': 0x20000000,
    'SZ_1G':   0x40000000, 'SZ_2G':   0x80000000,
    'SZ_4G':  0x100000000
}

RE_REMOVE_DEFCONFIG = re.compile(r'(.*)_defconfig')

# CONFIG symbols present in the build system (from Linux) but not actually used
# in U-Boot; KCONFIG symbols
IGNORE_SYMS = ['DEBUG_SECTION_MISMATCH', 'FTRACE_MCOUNT_RECORD', 'GCOV_KERNEL',
               'GCOV_PROFILE_ALL', 'KALLSYMS', 'KASAN', 'MODVERSIONS', 'SHELL',
               'TPL_BUILD', 'VPL_BUILD', 'IS_ENABLED', 'FOO', 'IF_ENABLED_INT',
               'IS_ENABLED_', 'IS_ENABLED_1', 'IS_ENABLED_2', 'IS_ENABLED_3',
               'SPL_', 'TPL_', 'SPL_FOO', 'TPL_FOO', 'TOOLS_FOO',
               'ACME', 'SPL_ACME', 'TPL_ACME', 'TRACE_BRANCH_PROFILING',
               'VAL', '_UNDEFINED', 'SPL_BUILD', ]

SPL_PREFIXES = ['SPL_', 'TPL_', 'VPL_', 'TOOLS_']

### helper functions ###
def check_top_directory():
    """Exit if we are not at the top of source directory."""
    for fname in 'README', 'Licenses':
        if not os.path.exists(fname):
            sys.exit('Please run at the top of source directory.')

def check_clean_directory():
    """Exit if the source tree is not clean."""
    for fname in '.config', 'include/config':
        if os.path.exists(fname):
            sys.exit("source tree is not clean, please run 'make mrproper'")

def get_make_cmd():
    """Get the command name of GNU Make.

    U-Boot needs GNU Make for building, but the command name is not
    necessarily "make". (for example, "gmake" on FreeBSD).
    Returns the most appropriate command name on your system.
    """
    with subprocess.Popen([SHOW_GNU_MAKE], stdout=subprocess.PIPE) as proc:
        ret = proc.communicate()
        if proc.returncode:
            sys.exit('GNU Make not found')
    return ret[0].rstrip()

def get_matched_defconfig(line):
    """Get the defconfig files that match a pattern

    Args:
        line (str): Path or filename to match, e.g. 'configs/snow_defconfig' or
            'k2*_defconfig'. If no directory is provided, 'configs/' is
            prepended

    Returns:
        list of str: a list of matching defconfig files
    """
    dirname = os.path.dirname(line)
    if dirname:
        pattern = line
    else:
        pattern = os.path.join('configs', line)
    return glob.glob(pattern) + glob.glob(pattern + '_defconfig')

def get_matched_defconfigs(defconfigs_file):
    """Get all the defconfig files that match the patterns in a file.

    Args:
        defconfigs_file (str): File containing a list of defconfigs to process,
            or '-' to read the list from stdin

    Returns:
        list of str: A list of paths to defconfig files, with no duplicates
    """
    defconfigs = []
    with ExitStack() as stack:
        if defconfigs_file == '-':
            inf = sys.stdin
            defconfigs_file = 'stdin'
        else:
            inf = stack.enter_context(open(defconfigs_file, encoding='utf-8'))
        for i, line in enumerate(inf):
            line = line.strip()
            if not line:
                continue # skip blank lines silently
            if ' ' in line:
                line = line.split(' ')[0]  # handle 'git log' input
            matched = get_matched_defconfig(line)
            if not matched:
                print(f"warning: {defconfigs_file}:{i + 1}: no defconfig matched '{line}'",
                      file=sys.stderr)

            defconfigs += matched

    # use set() to drop multiple matching
    return [defconfig[len('configs') + 1:]  for defconfig in set(defconfigs)]

def get_all_defconfigs():
    """Get all the defconfig files under the configs/ directory.

    Returns:
        list of str: List of paths to defconfig files
    """
    defconfigs = []
    for (dirpath, _, filenames) in os.walk('configs'):
        dirpath = dirpath[len('configs') + 1:]
        for filename in fnmatch.filter(filenames, '*_defconfig'):
            defconfigs.append(os.path.join(dirpath, filename))

    return defconfigs

def write_file(fname, data):
    """Write data to a file

    Args:
        fname (str): Filename to write to
        data (list of str): Lines to write (with or without trailing newline);
            or str to write
    """
    with open(fname, 'w', encoding='utf-8') as out:
        if isinstance(data, list):
            for line in data:
                print(line.rstrip('\n'), file=out)
        else:
            out.write(data)

def read_file(fname, as_lines=True, skip_unicode=False):
    """Read a file and return the contents

    Args:
        fname (str): Filename to read from
        as_lines (bool): Return file contents as a list of lines
        skip_unicode (bool): True to report unicode errors and continue

    Returns:
        iter of str: List of ;ines from the file with newline removed; str if
            as_lines is False with newlines intact; or None if a unicode error
            occurred

    Raises:
        UnicodeDecodeError: Unicode error occurred when reading
    """
    with open(fname, encoding='utf-8') as inf:
        try:
            if as_lines:
                return [line.rstrip('\n') for line in inf.readlines()]
            return inf.read()
        except UnicodeDecodeError as exc:
            if not skip_unicode:
                raise
            print(f"Failed on file '{fname}: {exc}")
            return None


### classes ###
class Progress:
    """Progress Indicator"""

    def __init__(self, col, total):
        """Create a new progress indicator.

        Args:
            col (terminal.Color): Colour-output class
            total (int): A number of defconfig files to process.

            current (int): Number of boards processed so far
            failed (int): Number of failed boards
            failure_msg (str): Message indicating number of failures, '' if none
        """
        self.col = col
        self.total = total

        self.current = 0
        self.good = 0
        self.failed = None
        self.failure_msg = None

    def inc(self, success):
        """Increment the number of processed defconfig files.

        Args:
            success (bool): True if processing succeeded
        """
        self.good += success
        self.current += 1

    def show(self):
        """Display the progress."""
        if self.current != self.total:
            line = self.col.build(self.col.GREEN, f'{self.good:5d}')
            line += self.col.build(self.col.RED,
                                   f'{self.current - self.good:5d}')
            line += self.col.build(self.col.MAGENTA,
                                   f'/{self.total - self.current}')
            print(f'{line}  \r', end='')
        sys.stdout.flush()

    def completed(self):
        """Set up extra properties when completed"""
        self.failed = self.total - self.good
        self.failure_msg = f'{self.failed} failed, ' if self.failed else ''


def scan_kconfig():
    """Scan all the Kconfig files and create a Config object

    Returns:
        Kconfig object
    """
    # Define environment variables referenced from Kconfig
    os.environ['srctree'] = os.getcwd()
    os.environ['UBOOTVERSION'] = 'dummy'
    os.environ['KCONFIG_OBJDIR'] = ''
    os.environ['CC'] = 'gcc'
    return kconfiglib.Kconfig()


# pylint: disable=R0903
class KconfigParser:
    """A parser of .config and include/autoconf.mk."""

    re_arch = re.compile(r'CONFIG_SYS_ARCH="(.*)"')
    re_cpu = re.compile(r'CONFIG_SYS_CPU="(.*)"')

    def __init__(self, args, build_dir):
        """Create a new parser.

        Args:
          args (Namespace): program arguments
          build_dir: Build directory.
        """
        self.args = args
        self.dotconfig = os.path.join(build_dir, '.config')
        self.autoconf = os.path.join(build_dir, 'include', 'autoconf.mk')
        self.spl_autoconf = os.path.join(build_dir, 'spl', 'include',
                                         'autoconf.mk')
        self.config_autoconf = os.path.join(build_dir, AUTO_CONF_PATH)
        self.defconfig = os.path.join(build_dir, 'defconfig')

    def get_arch(self):
        """Parse .config file and return the architecture.

        Returns:
          Architecture name (e.g. 'arm').
        """
        arch = ''
        cpu = ''
        for line in read_file(self.dotconfig):
            m_arch = self.re_arch.match(line)
            if m_arch:
                arch = m_arch.group(1)
                continue
            m_cpu = self.re_cpu.match(line)
            if m_cpu:
                cpu = m_cpu.group(1)

        if not arch:
            return None

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

        return arch


class DatabaseThread(threading.Thread):
    """This thread processes results from Slot threads.

    It collects the data in the master config directary. There is only one
    result thread, and this helps to serialise the build output.
    """
    def __init__(self, config_db, db_queue):
        """Set up a new result thread

        Args:
            builder: Builder which will be sent each result
        """
        threading.Thread.__init__(self)
        self.config_db = config_db
        self.db_queue= db_queue

    def run(self):
        """Called to start up the result thread.

        We collect the next result job and pass it on to the build.
        """
        while True:
            defconfig, configs = self.db_queue.get()
            self.config_db[defconfig] = configs
            self.db_queue.task_done()


class Slot:

    """A slot to store a subprocess.

    Each instance of this class handles one subprocess.
    This class is useful to control multiple threads
    for faster processing.
    """

    def __init__(self, toolchains, args, progress, devnull, make_cmd,
                 reference_src_dir, db_queue):
        """Create a new process slot.

        Args:
          toolchains: Toolchains object containing toolchains.
          args: Program arguments
          progress: A progress indicator.
          devnull: A file object of '/dev/null'.
          make_cmd: command name of GNU Make.
          reference_src_dir: Determine the true starting config state from this
                             source tree.
          db_queue: output queue to write config info for the database
          col (terminal.Color): Colour object
        """
        self.toolchains = toolchains
        self.args = args
        self.progress = progress
        self.build_dir = tempfile.mkdtemp()
        self.devnull = devnull
        self.make_cmd = (make_cmd, 'O=' + self.build_dir)
        self.reference_src_dir = reference_src_dir
        self.db_queue = db_queue
        self.col = progress.col
        self.parser = KconfigParser(args, self.build_dir)
        self.state = STATE_IDLE
        self.failed_boards = set()
        self.defconfig = None
        self.log = []
        self.current_src_dir = None
        self.proc = None

    def __del__(self):
        """Delete the working directory

        This function makes sure the temporary directory is cleaned away
        even if Python suddenly dies due to error.  It should be done in here
        because it is guaranteed the destructor is always invoked when the
        instance of the class gets unreferenced.

        If the subprocess is still running, wait until it finishes.
        """
        if self.state != STATE_IDLE:
            while self.proc.poll() is None:
                pass
        shutil.rmtree(self.build_dir)

    def add(self, defconfig):
        """Assign a new subprocess for defconfig and add it to the slot.

        If the slot is vacant, create a new subprocess for processing the
        given defconfig and add it to the slot.  Just returns False if
        the slot is occupied (i.e. the current subprocess is still running).

        Args:
          defconfig (str): defconfig name.

        Returns:
          Return True on success or False on failure
        """
        if self.state != STATE_IDLE:
            return False

        self.defconfig = defconfig
        self.log = []
        self.current_src_dir = self.reference_src_dir
        self.do_defconfig()
        return True

    def poll(self):
        """Check the status of the subprocess and handle it as needed.

        Returns True if the slot is vacant (i.e. in idle state).
        If the configuration is successfully finished, assign a new
        subprocess to build include/autoconf.mk.
        If include/autoconf.mk is generated, invoke the parser to
        parse the .config and the include/autoconf.mk, moving
        config options to the .config as needed.
        If the .config was updated, run "make savedefconfig" to sync
        it, update the original defconfig, and then set the slot back
        to the idle state.

        Returns:
          Return True if the subprocess is terminated, False otherwise
        """
        if self.state == STATE_IDLE:
            return True

        if self.proc.poll() is None:
            return False

        if self.proc.poll() != 0:
            self.handle_error()
        elif self.state == STATE_DEFCONFIG:
            if self.reference_src_dir and not self.current_src_dir:
                self.do_savedefconfig()
            else:
                self.do_autoconf()
        elif self.state == STATE_AUTOCONF:
            if self.current_src_dir:
                self.current_src_dir = None
                self.do_defconfig()
            elif self.args.build_db:
                self.do_build_db()
            else:
                self.do_savedefconfig()
        elif self.state == STATE_SAVEDEFCONFIG:
            self.update_defconfig()
        else:
            sys.exit('Internal Error. This should not happen.')

        return self.state == STATE_IDLE

    def handle_error(self):
        """Handle error cases."""

        self.log.append(self.col.build(self.col.RED, 'Failed to process',
                                       bright=True))
        if self.args.verbose:
            for line in self.proc.stderr.read().decode().splitlines():
                self.log.append(self.col.build(self.col.CYAN, line, True))
        self.finish(False)

    def do_defconfig(self):
        """Run 'make <board>_defconfig' to create the .config file."""

        cmd = list(self.make_cmd)
        cmd.append(self.defconfig)
        # pylint: disable=R1732
        self.proc = subprocess.Popen(cmd, stdout=self.devnull,
                                     stderr=subprocess.PIPE,
                                     cwd=self.current_src_dir)
        self.state = STATE_DEFCONFIG

    def do_autoconf(self):
        """Run 'make AUTO_CONF_PATH'."""

        arch = self.parser.get_arch()
        try:
            tchain = self.toolchains.Select(arch)
        except ValueError:
            self.log.append(self.col.build(
                self.col.YELLOW,
                f"Tool chain for '{arch}' is missing: do nothing"))
            self.finish(False)
            return
        env = tchain.MakeEnvironment(False)

        cmd = list(self.make_cmd)
        cmd.append('KCONFIG_IGNORE_DUPLICATES=1')
        cmd.append(AUTO_CONF_PATH)
        # pylint: disable=R1732
        self.proc = subprocess.Popen(cmd, stdout=self.devnull, env=env,
                                     stderr=subprocess.PIPE,
                                     cwd=self.current_src_dir)
        self.state = STATE_AUTOCONF

    def do_build_db(self):
        """Add the board to the database"""
        configs = {}
        for line in read_file(os.path.join(self.build_dir, AUTO_CONF_PATH)):
            if line.startswith('CONFIG'):
                config, value = line.split('=', 1)
                configs[config] = value.rstrip()
        self.db_queue.put([self.defconfig, configs])
        self.finish(True)

    def do_savedefconfig(self):
        """Update the .config and run 'make savedefconfig'."""
        if not self.args.force_sync:
            self.finish(True)
            return

        cmd = list(self.make_cmd)
        cmd.append('savedefconfig')
        # pylint: disable=R1732
        self.proc = subprocess.Popen(cmd, stdout=self.devnull,
                                     stderr=subprocess.PIPE)
        self.state = STATE_SAVEDEFCONFIG

    def update_defconfig(self):
        """Update the input defconfig and go back to the idle state."""
        orig_defconfig = os.path.join('configs', self.defconfig)
        new_defconfig = os.path.join(self.build_dir, 'defconfig')
        updated = not filecmp.cmp(orig_defconfig, new_defconfig)

        if updated:
            self.log.append(
                self.col.build(self.col.BLUE, 'defconfig updated', bright=True))

        if not self.args.dry_run and updated:
            shutil.move(new_defconfig, orig_defconfig)
        self.finish(True)

    def finish(self, success):
        """Display log along with progress and go to the idle state.

        Args:
          success (bool): Should be True when the defconfig was processed
                   successfully, or False when it fails.
        """
        # output at least 30 characters to hide the "* defconfigs out of *".
        name = self.defconfig[:-len('_defconfig')]
        if self.log:

            # Put the first log line on the first line
            log = name.ljust(20) + ' ' + self.log[0]

            if len(self.log) > 1:
                log += '\n' + '\n'.join(['    ' + s for s in self.log[1:]])
            # Some threads are running in parallel.
            # Print log atomically to not mix up logs from different threads.
            print(log, file=(sys.stdout if success else sys.stderr))

        if not success:
            if self.args.exit_on_error:
                sys.exit('Exit on error.')
            # If --exit-on-error flag is not set, skip this board and continue.
            # Record the failed board.
            self.failed_boards.add(name)

        self.progress.inc(success)
        self.progress.show()
        self.state = STATE_IDLE

    def get_failed_boards(self):
        """Returns a set of failed boards (defconfigs) in this slot.
        """
        return self.failed_boards

class Slots:
    """Controller of the array of subprocess slots."""

    def __init__(self, toolchains, args, progress, reference_src_dir, db_queue):
        """Create a new slots controller.

        Args:
            toolchains (Toolchains): Toolchains object containing toolchains
            args (Namespace): Program arguments
            progress (Progress): A progress indicator.
            reference_src_dir (str): Determine the true starting config state
                from this source tree (None for none)
            db_queue (Queue): output queue to write config info for the database
        """
        self.args = args
        self.slots = []
        self.progress = progress
        self.col = progress.col
        devnull = subprocess.DEVNULL
        make_cmd = get_make_cmd()
        for _ in range(args.jobs):
            self.slots.append(Slot(toolchains, args, progress, devnull,
                                   make_cmd, reference_src_dir, db_queue))

    def add(self, defconfig):
        """Add a new subprocess if a vacant slot is found.

        Args:
          defconfig (str): defconfig name to be put into.

        Returns:
          Return True on success or False on failure
        """
        for slot in self.slots:
            if slot.add(defconfig):
                return True
        return False

    def available(self):
        """Check if there is a vacant slot.

        Returns:
          Return True if at lease one vacant slot is found, False otherwise.
        """
        for slot in self.slots:
            if slot.poll():
                return True
        return False

    def empty(self):
        """Check if all slots are vacant.

        Returns:
          Return True if all the slots are vacant, False otherwise.
        """
        ret = True
        for slot in self.slots:
            if not slot.poll():
                ret = False
        return ret

    def write_failed_boards(self):
        """Show the results of processing"""
        boards = set()

        for slot in self.slots:
            boards |= slot.get_failed_boards()

        if boards:
            boards = '\n'.join(sorted(boards)) + '\n'
            write_file(FAILED_LIST, boards)


class ReferenceSource:

    """Reference source against which original configs should be parsed."""

    def __init__(self, commit):
        """Create a reference source directory based on a specified commit.

        Args:
          commit: commit to git-clone
        """
        self.src_dir = tempfile.mkdtemp()
        print('Cloning git repo to a separate work directory...')
        subprocess.check_output(['git', 'clone', os.getcwd(), '.'],
                                cwd=self.src_dir)
        rev = subprocess.check_output(['git', 'rev-parse', '--short',
                                       commit]).strip()
        print(f"Checkout '{rev}' to build the original autoconf.mk.")
        subprocess.check_output(['git', 'checkout', commit],
                                stderr=subprocess.STDOUT, cwd=self.src_dir)

    def __del__(self):
        """Delete the reference source directory

        This function makes sure the temporary directory is cleaned away
        even if Python suddenly dies due to error.  It should be done in here
        because it is guaranteed the destructor is always invoked when the
        instance of the class gets unreferenced.
        """
        shutil.rmtree(self.src_dir)

    def get_dir(self):
        """Return the absolute path to the reference source directory."""

        return self.src_dir

def move_config(args):
    """Build database or sync config options to defconfig files.

    Args:
        args (Namespace): Program arguments

    Returns:
        tuple:
            config_db (dict of configs for each defconfig):
                key: defconfig name, e.g. "MPC8548CDS_legacy_defconfig"
                value: dict:
                    key: CONFIG option
                    value: Value of option
            Progress: Progress indicator
    """
    config_db = {}
    db_queue = queue.Queue()
    dbt = DatabaseThread(config_db, db_queue)
    dbt.daemon = True
    dbt.start()

    check_clean_directory()
    bsettings.setup('')

    # Get toolchains to use
    toolchains = toolchain.Toolchains()
    toolchains.GetSettings()
    toolchains.Scan(verbose=False)

    if args.git_ref:
        reference_src = ReferenceSource(args.git_ref)
        reference_src_dir = reference_src.get_dir()
    else:
        reference_src_dir = None

    if args.defconfigs:
        defconfigs = get_matched_defconfigs(args.defconfigs)
    else:
        defconfigs = get_all_defconfigs()

    col = terminal.Color(terminal.COLOR_NEVER if args.nocolour
                         else terminal.COLOR_IF_TERMINAL)
    progress = Progress(col, len(defconfigs))
    slots = Slots(toolchains, args, progress, reference_src_dir, db_queue)

    # Main loop to process defconfig files:
    #  Add a new subprocess into a vacant slot.
    #  Sleep if there is no available slot.
    for defconfig in defconfigs:
        while not slots.add(defconfig):
            while not slots.available():
                # No available slot: sleep for a while
                time.sleep(SLEEP_TIME)

    # wait until all the subprocesses finish
    while not slots.empty():
        time.sleep(SLEEP_TIME)

    slots.write_failed_boards()
    db_queue.join()
    progress.completed()
    return config_db, progress

def find_kconfig_rules(kconf, config, imply_config):
    """Check whether a config has a 'select' or 'imply' keyword

    Args:
        kconf (Kconfiglib.Kconfig): Kconfig object
        config (str): Name of config to check (without CONFIG_ prefix)
        imply_config (str): Implying config (without CONFIG_ prefix) which may
            or may not have an 'imply' for 'config')

    Returns:
        Symbol object for 'config' if found, else None
    """
    sym = kconf.syms.get(imply_config)
    if sym:
        for sel, _ in (sym.selects + sym.implies):
            if sel.name == config:
                return sym
    return None

def check_imply_rule(kconf, imply_config):
    """Check if we can add an 'imply' option

    This finds imply_config in the Kconfig and looks to see if it is possible
    to add an 'imply' for 'config' to that part of the Kconfig.

    Args:
        kconf (Kconfiglib.Kconfig): Kconfig object
        imply_config (str): Implying config (without CONFIG_ prefix) which may
            or may not have an 'imply' for 'config')

    Returns:
        tuple:
            str: filename of Kconfig file containing imply_config, or None if
                none
            int: line number within the Kconfig file, or 0 if none
            str: message indicating the result
    """
    sym = kconf.syms.get(imply_config)
    if not sym:
        return 'cannot find sym'
    nodes = sym.nodes
    if len(nodes) != 1:
        return f'{len(nodes)} locations'
    node = nodes[0]
    fname, linenum = node.filename, node.linenr
    cwd = os.getcwd()
    if cwd and fname.startswith(cwd):
        fname = fname[len(cwd) + 1:]
    file_line = f' at {fname}:{linenum}'
    data = read_file(fname)
    if data[linenum - 1] != f'config {imply_config}':
        return None, 0, f'bad sym format {data[linenum]}{file_line})'
    return fname, linenum, f'adding{file_line}'

def add_imply_rule(config, fname, linenum):
    """Add a new 'imply' option to a Kconfig

    Args:
        config (str): config option to add an imply for (without CONFIG_ prefix)
        fname (str): Kconfig filename to update
        linenum (int): Line number to place the 'imply' before

    Returns:
        Message indicating the result
    """
    file_line = f' at {fname}:{linenum}'
    data = read_file(fname)
    linenum -= 1

    for offset, line in enumerate(data[linenum:]):
        if line.strip().startswith('help') or not line:
            data.insert(linenum + offset, f'\timply {config}')
            write_file(fname, data)
            return f'added{file_line}'

    return 'could not insert%s'

(IMPLY_MIN_2, IMPLY_TARGET, IMPLY_CMD, IMPLY_NON_ARCH_BOARD) = (
    1, 2, 4, 8)

IMPLY_FLAGS = {
    'min2': [IMPLY_MIN_2, 'Show options which imply >2 boards (normally >5)'],
    'target': [IMPLY_TARGET, 'Allow CONFIG_TARGET_... options to imply'],
    'cmd': [IMPLY_CMD, 'Allow CONFIG_CMD_... to imply'],
    'non-arch-board': [
        IMPLY_NON_ARCH_BOARD,
        'Allow Kconfig options outside arch/ and /board/ to imply'],
}


def read_database():
    """Read in the config database

    Returns:
        tuple:
            set of all config options seen (each a str)
            set of all defconfigs seen (each a str)
            dict of configs for each defconfig:
                key: defconfig name, e.g. "MPC8548CDS_legacy_defconfig"
                value: dict:
                    key: CONFIG option
                    value: Value of option
            dict of defconfigs for each config:
                key: CONFIG option
                value: set of boards using that option

    """
    configs = {}

    # key is defconfig name, value is dict of (CONFIG_xxx, value)
    config_db = {}

    # Set of all config options we have seen
    all_configs = set()

    # Set of all defconfigs we have seen
    all_defconfigs = set()

    defconfig_db = collections.defaultdict(set)
    defconfig = None
    for line in read_file(CONFIG_DATABASE):
        line = line.rstrip()
        if not line:  # Separator between defconfigs
            config_db[defconfig] = configs
            all_defconfigs.add(defconfig)
            configs = {}
        elif line[0] == ' ':  # CONFIG line
            config, value = line.strip().split('=', 1)
            configs[config] = value
            defconfig_db[config].add(defconfig)
            all_configs.add(config)
        else:  # New defconfig
            defconfig = line

    return all_configs, all_defconfigs, config_db, defconfig_db


def do_imply_config(config_list, add_imply, imply_flags, skip_added,
                    check_kconfig=True, find_superset=False):
    """Find CONFIG options which imply those in the list

    Some CONFIG options can be implied by others and this can help to reduce
    the size of the defconfig files. For example, CONFIG_X86 implies
    CONFIG_CMD_IRQ, so we can put 'imply CMD_IRQ' under 'config X86' and
    all x86 boards will have that option, avoiding adding CONFIG_CMD_IRQ to
    each of the x86 defconfig files.

    This function uses the qconfig database to find such options. It
    displays a list of things that could possibly imply those in the list.
    The algorithm ignores any that start with CONFIG_TARGET since these
    typically refer to only a few defconfigs (often one). It also does not
    display a config with less than 5 defconfigs.

    The algorithm works using sets. For each target config in config_list:
        - Get the set 'defconfigs' which use that target config
        - For each config (from a list of all configs):
            - Get the set 'imply_defconfig' of defconfigs which use that config
            -
            - If imply_defconfigs contains anything not in defconfigs then
              this config does not imply the target config

    Args:
        config_list (list of str): List of CONFIG options to check
        add_imply (bool): Automatically add an 'imply' for each config.
        imply_flags (int): Flags which control which implying configs are allowed
           (IMPLY_...)
        skip_added (bool): Don't show options which already have an imply added.
        check_kconfig (bool): Check if implied symbols already have an 'imply' or
            'select' for the target config, and show this information if so.
        find_superset (bool): True to look for configs which are a superset of those
            already found. So for example if CONFIG_EXYNOS5 implies an option,
            but CONFIG_EXYNOS covers a larger set of defconfigs and also
            implies that option, this will drop the former in favour of the
            latter. In practice this option has not proved very used.

    Note the terminoloy:
        config - a CONFIG_XXX options (a string, e.g. 'CONFIG_CMD_EEPROM')
        defconfig - a defconfig file (a string, e.g. 'configs/snow_defconfig')
    """
    kconf = scan_kconfig() if check_kconfig else None
    if add_imply and add_imply != 'all':
        add_imply = add_imply.split(',')

    all_configs, all_defconfigs, _, defconfig_db = read_database()

    # Work through each target config option in turn, independently
    for config in config_list:
        defconfigs = defconfig_db.get(config)
        if not defconfigs:
            print(f'{config} not found in any defconfig')
            continue

        # Get the set of defconfigs without this one (since a config cannot
        # imply itself)
        non_defconfigs = all_defconfigs - defconfigs
        num_defconfigs = len(defconfigs)
        print(f'{config} found in {num_defconfigs}/{len(all_configs)} defconfigs')

        # This will hold the results: key=config, value=defconfigs containing it
        imply_configs = {}
        rest_configs = all_configs - set([config])

        # Look at every possible config, except the target one
        for imply_config in rest_configs:
            if 'ERRATUM' in imply_config:
                continue
            if not imply_flags & IMPLY_CMD:
                if 'CONFIG_CMD' in imply_config:
                    continue
            if not imply_flags & IMPLY_TARGET:
                if 'CONFIG_TARGET' in imply_config:
                    continue

            # Find set of defconfigs that have this config
            imply_defconfig = defconfig_db[imply_config]

            # Get the intersection of this with defconfigs containing the
            # target config
            common_defconfigs = imply_defconfig & defconfigs

            # Get the set of defconfigs containing this config which DO NOT
            # also contain the taret config. If this set is non-empty it means
            # that this config affects other defconfigs as well as (possibly)
            # the ones affected by the target config. This means it implies
            # things we don't want to imply.
            not_common_defconfigs = imply_defconfig & non_defconfigs
            if not_common_defconfigs:
                continue

            # If there are common defconfigs, imply_config may be useful
            if common_defconfigs:
                skip = False
                if find_superset:
                    for prev in list(imply_configs.keys()):
                        prev_count = len(imply_configs[prev])
                        count = len(common_defconfigs)
                        if (prev_count > count and
                            (imply_configs[prev] & common_defconfigs ==
                            common_defconfigs)):
                            # skip imply_config because prev is a superset
                            skip = True
                            break
                        if count > prev_count:
                            # delete prev because imply_config is a superset
                            del imply_configs[prev]
                if not skip:
                    imply_configs[imply_config] = common_defconfigs

        # Now we have a dict imply_configs of configs which imply each config
        # The value of each dict item is the set of defconfigs containing that
        # config. Rank them so that we print the configs that imply the largest
        # number of defconfigs first.
        ranked_iconfigs = sorted(imply_configs,
                            key=lambda k: len(imply_configs[k]), reverse=True)
        kconfig_info = ''
        cwd = os.getcwd()
        add_list = collections.defaultdict(list)
        for iconfig in ranked_iconfigs:
            num_common = len(imply_configs[iconfig])

            # Don't bother if there are less than 5 defconfigs affected.
            if num_common < (2 if imply_flags & IMPLY_MIN_2 else 5):
                continue
            missing = defconfigs - imply_configs[iconfig]
            missing_str = ', '.join(missing) if missing else 'all'
            missing_str = ''
            show = True
            if kconf:
                sym = find_kconfig_rules(kconf, config[CONFIG_LEN:],
                                         iconfig[CONFIG_LEN:])
                kconfig_info = ''
                if sym:
                    nodes = sym.nodes
                    if len(nodes) == 1:
                        fname, linenum = nodes[0].filename, nodes[0].linenr
                        if cwd and fname.startswith(cwd):
                            fname = fname[len(cwd) + 1:]
                        kconfig_info = f'{fname}:{linenum}'
                        if skip_added:
                            show = False
                else:
                    sym = kconf.syms.get(iconfig[CONFIG_LEN:])
                    fname = ''
                    if sym:
                        nodes = sym.nodes
                        if len(nodes) == 1:
                            fname, linenum = nodes[0].filename, nodes[0].linenr
                            if cwd and fname.startswith(cwd):
                                fname = fname[len(cwd) + 1:]
                    in_arch_board = not sym or (fname.startswith('arch') or
                                                fname.startswith('board'))
                    if (not in_arch_board and
                        not imply_flags & IMPLY_NON_ARCH_BOARD):
                        continue

                    if add_imply and (add_imply == 'all' or
                                      iconfig in add_imply):
                        fname, linenum, kconfig_info = (check_imply_rule(kconf,
                                iconfig[CONFIG_LEN:]))
                        if fname:
                            add_list[fname].append(linenum)

            if show and kconfig_info != 'skip':
                print(f'{num_common:5} : '
                      f'{iconfig.ljust(30)}{kconfig_info.ljust(25)} {missing_str}')

        # Having collected a list of things to add, now we add them. We process
        # each file from the largest line number to the smallest so that
        # earlier additions do not affect our line numbers. E.g. if we added an
        # imply at line 20 it would change the position of each line after
        # that.
        for fname, linenums in add_list.items():
            for linenum in sorted(linenums, reverse=True):
                add_imply_rule(config[CONFIG_LEN:], fname, linenum)

def defconfig_matches(configs, re_match, re_val):
    """Check if any CONFIG option matches a regex

    The match must be complete, i.e. from the start to end of the CONFIG option.

    Args:
        configs (dict): Dict of CONFIG options:
            key: CONFIG option
            value: Value of option
        re_match (re.Pattern): Match to check
        re_val (re.Pattern): Regular expression to check against value (or None)

    Returns:
        bool: True if any CONFIG matches the regex
    """
    for cfg, val in configs.items():
        if re_match.fullmatch(cfg):
            if not re_val or re_val.fullmatch(val):
                return True
    return False

def do_find_config(config_list, list_format):
    """Find boards with a given combination of CONFIGs

    Args:
        config_list (list of str): List of CONFIG options to check (each a regex
            consisting of a config option, with or without a CONFIG_ prefix. If
            an option is preceded by a tilde (~) then it must be false,
            otherwise it must be true)
        list_format (bool): True to write in 'list' format, one board name per
            line

    Returns:
        int: exit code (0 for success)
    """
    _, all_defconfigs, config_db, _ = read_database()

    # Start with all defconfigs
    out = all_defconfigs

    # Work through each config in turn
    for item in config_list:
        # Get the real config name and whether we want this config or not
        cfg = item
        want = True
        if cfg[0] == '~':
            want = False
            cfg = cfg[1:]
        val = None
        re_val = None
        if '=' in cfg:
            cfg, val = cfg.split('=', maxsplit=1)
            re_val = re.compile(val)

        # Search everything that is still in the running. If it has a config
        # that we want, or doesn't have one that we don't, add it into the
        # running for the next stage
        in_list = out
        out = set()
        re_match = re.compile(cfg)
        for defc in in_list:
            has_cfg = defconfig_matches(config_db[defc], re_match, re_val)
            if has_cfg == want:
                out.add(defc)
    if not list_format:
        print(f'{len(out)} matches')
    sep = '\n' if list_format else ' '
    print(sep.join(item.split('_defconfig')[0] for item in sorted(list(out))))
    return 0


def prefix_config(cfg):
    """Prefix a config with CONFIG_ if needed

    This handles ~ operator, which indicates that the CONFIG should be disabled

    >>> prefix_config('FRED')
    'CONFIG_FRED'
    >>> prefix_config('CONFIG_FRED')
    'CONFIG_FRED'
    >>> prefix_config('~FRED')
    '~CONFIG_FRED'
    >>> prefix_config('~CONFIG_FRED')
    '~CONFIG_FRED'
    >>> prefix_config('A123')
    'CONFIG_A123'
    """
    oper = ''
    if cfg[0] == '~':
        oper = cfg[0]
        cfg = cfg[1:]
    if not cfg.startswith('CONFIG_'):
        cfg = 'CONFIG_' + cfg
    return oper + cfg


RE_MK_CONFIGS = re.compile(r'CONFIG_(\$\(SPL_(?:TPL_)?\))?([A-Za-z0-9_]*)')
RE_IFDEF = re.compile(r'(ifdef|ifndef)')
RE_C_CONFIGS = re.compile(r'CONFIG_([A-Za-z0-9_]*)')
RE_CONFIG_IS = re.compile(r'CONFIG_IS_ENABLED\(([A-Za-z0-9_]*)\)')

class ConfigUse:
    """Tracks whether a config relates to SPL or not"""
    def __init__(self, cfg, is_spl, fname, rest):
        """Set up a new ConfigUse

        Args:
            cfg (str): CONFIG option, without any CONFIG_ or SPL_ prefix
            is_spl (bool): True if this option relates to SPL
            fname (str): Makefile filename where the CONFIG option was found
            rest (str): Line of the Makefile
        """
        self.cfg = cfg
        self.is_spl = is_spl
        self.fname = fname
        self.rest = rest

    def __hash__(self):
        return hash((self.cfg, self.is_spl))

def scan_makefiles(fnames):
    """Scan Makefiles looking for Kconfig options

    Looks for uses of CONFIG options in Makefiles

    Args:
        fnames (list of tuple):
            str: Makefile filename where the option was found
            str: Line of the Makefile

    Returns:
        tuple:
            dict: all_uses
                key (ConfigUse): object
                value (list of str): matching lines
            dict: Uses by filename
                key (str): filename
                value (set of ConfigUse): uses in that filename

    >>> RE_MK_CONFIGS.search('CONFIG_FRED').groups()
    (None, 'FRED')
    >>> RE_MK_CONFIGS.search('CONFIG_$(SPL_)MARY').groups()
    ('$(SPL_)', 'MARY')
    >>> RE_MK_CONFIGS.search('CONFIG_$(SPL_TPL_)MARY').groups()
    ('$(SPL_TPL_)', 'MARY')
    """
    all_uses = collections.defaultdict(list)
    fname_uses = {}
    for fname, rest in fnames:
        m_iter = RE_MK_CONFIGS.finditer(rest)
        for mat in m_iter:
            real_opt = mat.group(2)
            if real_opt == '':
                continue
            is_spl = False
            if mat.group(1):
                is_spl = True
            use = ConfigUse(real_opt, is_spl, fname, rest)
            if fname not in fname_uses:
                fname_uses[fname] = set()
            fname_uses[fname].add(use)
            all_uses[use].append(rest)
    return all_uses, fname_uses


def scan_src_files(fnames):
    """Scan source files (other than Makefiles) looking for Kconfig options

    Looks for uses of CONFIG options

    Args:
        fnames (list of tuple):
            str: Makefile filename where the option was found
            str: Line of the Makefile

    Returns:
        tuple:
            dict: all_uses
                key (ConfigUse): object
                value (list of str): matching lines
            dict: Uses by filename
                key (str): filename
                value (set of ConfigUse): uses in that filename

    >>> RE_C_CONFIGS.search('CONFIG_FRED').groups()
    ('FRED',)
    >>> RE_CONFIG_IS.search('CONFIG_IS_ENABLED(MARY)').groups()
    ('MARY',)
    >>> RE_CONFIG_IS.search('#if CONFIG_IS_ENABLED(OF_PLATDATA)').groups()
    ('OF_PLATDATA',)
    """
    fname = None
    rest = None

    def add_uses(m_iter, is_spl):
        for mat in m_iter:
            real_opt = mat.group(1)
            if real_opt == '':
                continue
            use = ConfigUse(real_opt, is_spl, fname, rest)
            if fname not in fname_uses:
                fname_uses[fname] = set()
            fname_uses[fname].add(use)
            all_uses[use].append(rest)

    all_uses = collections.defaultdict(list)
    fname_uses = {}
    for fname, rest in fnames:
        m_iter = RE_C_CONFIGS.finditer(rest)
        add_uses(m_iter, False)

        m_iter2 = RE_CONFIG_IS.finditer(rest)
        add_uses(m_iter2, True)

    return all_uses, fname_uses


MODE_NORMAL, MODE_SPL, MODE_PROPER = range(3)

def do_scan_source(path, do_update):
    """Scan the source tree for Kconfig inconsistencies

    Args:
        path (str): Path to source tree
        do_update (bool) : True to write to scripts/kconf_... files
    """
    def is_not_proper(name):
        for prefix in SPL_PREFIXES:
            if name.startswith(prefix):
                return name[len(prefix):]
        return False

    def check_not_found(all_uses, spl_mode):
        """Check for Kconfig options mentioned in the source but not in Kconfig

        Args:
            all_uses (dict):
                key (ConfigUse): object
                value (list of str): matching lines
            spl_mode (int): If MODE_SPL, look at source code which implies
                an SPL_ option, but for which there is none;
                for MOD_PROPER, look at source code which implies a Proper
                option (i.e. use of CONFIG_IS_ENABLED() or $(SPL_) or
                $(SPL_TPL_) but for which there none;
                if MODE_NORMAL, ignore SPL

        Returns:
            dict:
                key (str): CONFIG name (without 'CONFIG_' prefix
                value (list of ConfigUse): List of uses of this CONFIG
        """
        # Make sure we know about all the options
        not_found = collections.defaultdict(list)
        for use, _ in all_uses.items():
            name = use.cfg
            if name in IGNORE_SYMS:
                continue
            check = True

            if spl_mode == MODE_SPL:
                check = use.is_spl

                # If it is an SPL symbol, try prepending all SPL_ prefixes to
                # find at least one SPL symbol
                if use.is_spl:
                    for prefix in SPL_PREFIXES:
                        try_name = prefix + name
                        sym = kconf.syms.get(try_name)
                        if sym:
                            break
                    if not sym:
                        not_found[f'SPL_{name}'].append(use)
                    continue
            elif spl_mode == MODE_PROPER:
                # Try to find the Proper version of this symbol, i.e. without
                # the SPL_ prefix
                proper_name = is_not_proper(name)
                if proper_name:
                    name = proper_name
                elif not use.is_spl:
                    check = False
            else: # MODE_NORMAL
                sym = kconf.syms.get(name)
                if not sym:
                    proper_name = is_not_proper(name)
                    if proper_name:
                        name = proper_name
                    sym = kconf.syms.get(name)
                if not sym:
                    for prefix in SPL_PREFIXES:
                        try_name = prefix + name
                        sym = kconf.syms.get(try_name)
                        if sym:
                            break
                if not sym:
                    not_found[name].append(use)
                continue

            sym = kconf.syms.get(name)
            if not sym and check:
                not_found[name].append(use)
        return not_found

    def show_uses(uses):
        """Show a list of uses along with their filename and code snippet

        Args:
            uses (dict):
                key (str): CONFIG name (without 'CONFIG_' prefix
                value (list of ConfigUse): List of uses of this CONFIG
        """
        for name in sorted(uses):
            print(f'{name}: ', end='')
            for i, use in enumerate(uses[name]):
                print(f'{"   " if i else ""}{use.fname}: {use.rest.strip()}')


    print('Scanning Kconfig')
    kconf = scan_kconfig()
    print(f'Scanning source in {path}')
    args = ['git', 'grep', '-E', r'IS_ENABLED|\bCONFIG']
    with subprocess.Popen(args, stdout=subprocess.PIPE) as proc:
        out, _ = proc.communicate()
    lines = out.splitlines()
    re_fname = re.compile('^([^:]*):(.*)')
    src_list = []
    mk_list = []
    for line in lines:
        linestr = line.decode('utf-8')
        m_fname = re_fname.search(linestr)
        if not m_fname:
            continue
        fname, rest = m_fname.groups()
        dirname, leaf = os.path.split(fname)
        root, ext = os.path.splitext(leaf)
        if ext == '.autoconf':
            pass
        elif ext in ['.c', '.h', '.S', '.lds', '.dts', '.dtsi', '.asl', '.cfg',
                     '.env', '.tmpl']:
            src_list.append([fname, rest])
        elif 'Makefile' in root or ext == '.mk':
            mk_list.append([fname, rest])
        elif ext in ['.yml', '.sh', '.py', '.awk', '.pl', '.rst', '', '.sed']:
            pass
        elif 'Kconfig' in root or 'Kbuild' in root:
            pass
        elif 'README' in root:
            pass
        elif dirname in ['configs']:
            pass
        elif dirname.startswith('doc') or dirname.startswith('scripts/kconfig'):
            pass
        else:
            print(f'Not sure how to handle file {fname}')

    # Scan the Makefiles
    all_uses, _ = scan_makefiles(mk_list)

    spl_not_found = set()
    proper_not_found = set()

    # Make sure we know about all the options
    print('\nCONFIG options present in Makefiles but not Kconfig:')
    not_found = check_not_found(all_uses, MODE_NORMAL)
    show_uses(not_found)

    print('\nCONFIG options present in Makefiles but not Kconfig (SPL):')
    not_found = check_not_found(all_uses, MODE_SPL)
    show_uses(not_found)
    spl_not_found |= {is_not_proper(key) or key for key in not_found.keys()}

    print('\nCONFIG options used as Proper in Makefiles but without a non-SPL_ variant:')
    not_found = check_not_found(all_uses, MODE_PROPER)
    show_uses(not_found)
    proper_not_found |= {not_found.keys()}

    # Scan the source code
    all_uses, _ = scan_src_files(src_list)

    # Make sure we know about all the options
    print('\nCONFIG options present in source but not Kconfig:')
    not_found = check_not_found(all_uses, MODE_NORMAL)
    show_uses(not_found)

    print('\nCONFIG options present in source but not Kconfig (SPL):')
    not_found = check_not_found(all_uses, MODE_SPL)
    show_uses(not_found)
    spl_not_found |= {is_not_proper(key) or key for key in not_found.keys()}

    print('\nCONFIG options used as Proper in source but without a non-SPL_ variant:')
    not_found = check_not_found(all_uses, MODE_PROPER)
    show_uses(not_found)
    proper_not_found |= {not_found.keys()}

    print('\nCONFIG options used as SPL but without an SPL_ variant:')
    for item in sorted(spl_not_found):
        print(f'   {item}')

    print('\nCONFIG options used as Proper but without a non-SPL_ variant:')
    for item in sorted(proper_not_found):
        print(f'   {item}')

    # Write out the updated information
    if do_update:
        with open(os.path.join(path, 'scripts', 'conf_nospl'), 'w',
                  encoding='utf-8') as out:
            print('# These options should not be enabled in SPL builds\n',
                  file=out)
            for item in sorted(spl_not_found):
                print(item, file=out)
        with open(os.path.join(path, 'scripts', 'conf_noproper'), 'w',
                  encoding='utf-8') as out:
            print('# These options should not be enabled in Proper builds\n',
                  file=out)
            for item in sorted(proper_not_found):
                print(item, file=out)
    return 0


def parse_args():
    """Parse the program arguments

    Returns:
        tuple:
            argparse.ArgumentParser: parser
            argparse.Namespace: Parsed arguments
    """
    try:
        cpu_count = multiprocessing.cpu_count()
    except NotImplementedError:
        cpu_count = 1

    epilog = '''Move config options from headers to defconfig files. See
doc/develop/moveconfig.rst for documentation.'''

    parser = ArgumentParser(epilog=epilog)
    # Add arguments here
    parser.add_argument('-a', '--add-imply', type=str, default='',
                      help='comma-separated list of CONFIG options to add '
                      "an 'imply' statement to for the CONFIG in -i")
    parser.add_argument('-A', '--skip-added', action='store_true', default=False,
                      help="don't show options which are already marked as "
                      'implying others')
    parser.add_argument('-b', '--build-db', action='store_true', default=False,
                      help='build a CONFIG database')
    parser.add_argument('-C', '--commit', action='store_true', default=False,
                      help='Create a git commit for the operation')
    parser.add_argument('--nocolour', action='store_true', default=False,
                      help="don't display the log in colour")
    parser.add_argument('-d', '--defconfigs', type=str,
                      help='a file containing a list of defconfigs to move, '
                      "one per line (for example 'snow_defconfig') "
                      "or '-' to read from stdin")
    parser.add_argument('-e', '--exit-on-error', action='store_true',
                      default=False,
                      help='exit immediately on any error')
    parser.add_argument('-f', '--find', action='store_true', default=False,
                      help='Find boards with a given config combination')
    parser.add_argument('-i', '--imply', action='store_true', default=False,
                      help='find options which imply others')
    parser.add_argument('-l', '--list', action='store_true', default=False,
                      help='Show a sorted list of board names, one per line')
    parser.add_argument('-I', '--imply-flags', type=str, default='',
                      help="control the -i option ('help' for help")
    parser.add_argument('-j', '--jobs', type=int, default=cpu_count,
                      help='the number of jobs to run simultaneously')
    parser.add_argument('-n', '--dry-run', action='store_true', default=False,
                      help='perform a trial run (show log with no changes)')
    parser.add_argument('-r', '--git-ref', type=str,
                      help='the git ref to clone for building the autoconf.mk')
    parser.add_argument('-s', '--force-sync', action='store_true', default=False,
                      help='force sync by savedefconfig')
    parser.add_argument('-S', '--spl', action='store_true', default=False,
                      help='parse config options defined for SPL build')
    parser.add_argument('--scan-source', action='store_true', default=False,
                      help='scan source for uses of CONFIG options')
    parser.add_argument('-t', '--test', action='store_true', default=False,
                      help='run unit tests')
    parser.add_argument('-y', '--yes', action='store_true', default=False,
                      help="respond 'yes' to any prompts")
    parser.add_argument('-u', '--update', action='store_true', default=False,
                      help="update scripts/ files (use with --scan-source)")
    parser.add_argument('-v', '--verbose', action='store_true', default=False,
                      help='show any build errors as boards are built')
    parser.add_argument('configs', nargs='*')

    args = parser.parse_args()
    if not any((args.force_sync, args.build_db, args.imply, args.find,
                args.scan_source, args.test)):
        parser.print_usage()
        sys.exit(1)

    return parser, args


def imply(args):
    """Handle checking for flags which imply others

    Args:
        args (argparse.Namespace): Program arguments

    Returns:
        int: exit code (0 for success)
    """
    imply_flags = 0
    if args.imply_flags == 'all':
        imply_flags = -1

    elif args.imply_flags:
        for flag in args.imply_flags.split(','):
            bad = flag not in IMPLY_FLAGS
            if bad:
                print(f"Invalid flag '{flag}'")
            if flag == 'help' or bad:
                print("Imply flags: (separate with ',')")
                for name, info in IMPLY_FLAGS.items():
                    print(f' {name:-15s}: {info[1]}')
                return 1
            imply_flags |= IMPLY_FLAGS[flag][0]

    do_imply_config(args.configs, args.add_imply, imply_flags, args.skip_added)
    return 0


def add_commit(configs):
    """Add a commit indicating which CONFIG options were converted

    Args:
        configs (list of str) List of CONFIG_... options to process
    """
    subprocess.call(['git', 'add', '-u'])
    if configs:
        part = 'et al ' if len(configs) > 1 else ''
        msg = f'Convert {configs[0]} {part}to Kconfig'
        msg += ('\n\nThis converts the following to Kconfig:\n   %s\n' %
                '\n   '.join(configs))
    else:
        msg = 'configs: Resync with savedefconfig'
        msg += '\n\nRsync all defconfig files using moveconfig.py'
    subprocess.call(['git', 'commit', '-s', '-m', msg])


def write_db(config_db, progress):
    """Write the database to a file

    Args:
        config_db (dict of dict): configs for each defconfig
            key: defconfig name, e.g. "MPC8548CDS_legacy_defconfig"
            value: dict:
                key: CONFIG option
                value: Value of option
        progress (Progress): Progress indicator.

    Returns:
        int: exit code (0 for success)
    """
    col = progress.col
    with open(CONFIG_DATABASE, 'w', encoding='utf-8') as outf:
        for defconfig, configs in config_db.items():
            outf.write(f'{defconfig}\n')
            for config in sorted(configs.keys()):
                outf.write(f'   {config}={configs[config]}\n')
            outf.write('\n')
    print(col.build(
        col.RED if progress.failed else col.GREEN,
        f'{progress.failure_msg}{len(config_db)} boards written to {CONFIG_DATABASE}'))
    return 0


def move_done(progress):
    """Write a message indicating that the move is done

    Args:
        progress (Progress): Progress indicator.

    Returns:
        int: exit code (0 for success)
    """
    col = progress.col
    if progress.failed:
        print(col.build(col.RED, f'{progress.failure_msg}see {FAILED_LIST}', True))
    else:
        # Add enough spaces to overwrite the progress indicator
        print(col.build(
            col.GREEN, f'{progress.total} processed        ', bright=True))
    return 0

def do_tests():
    """Run doctests and unit tests (so far there are no unit tests)"""
    sys.argv = [sys.argv[0]]
    fail, _ = doctest.testmod()
    if fail:
        return 1
    unittest.main()
    return 0


def main():
    """Main program"""
    parser, args = parse_args()
    check_top_directory()

    # prefix the option name with CONFIG_ if missing
    args.configs = [prefix_config(cfg) for cfg in args.configs]

    if args.test:
        return do_tests()
    if args.scan_source:
        return do_scan_source(os.getcwd(), args.update)
    if args.imply:
        if imply(args):
            parser.print_usage()
            sys.exit(1)
        return 0
    if args.find:
        return do_find_config(args.configs, args.list)

    config_db, progress = move_config(args)

    if args.commit:
        add_commit(args.configs)

    if args.build_db:
        return write_db(config_db, progress)
    return move_done(progress)


if __name__ == '__main__':
    sys.exit(main())
