#!/usr/bin/env python3

# Copyright (c) 2018-2019, Ulf Magnusson
# SPDX-License-Identifier: ISC

"""
Implements oldconfig functionality.

  1. Loads existing .config
  2. Prompts for the value of all modifiable symbols/choices that
     aren't already set in the .config
  3. Writes an updated .config

The default input/output filename is '.config'. A different filename can be
passed in the KCONFIG_CONFIG environment variable.

When overwriting a configuration file, the old version is saved to
<filename>.old (e.g. .config.old).

Entering '?' displays the help text of the symbol/choice, if any.

Unlike 'make oldconfig', this script doesn't print menu titles and comments,
but gives Kconfig definition locations. Printing menus and comments would be
pretty easy to add: Look at the parents of each item, and print all menu
prompts and comments unless they have already been printed (assuming you want
to skip "irrelevant" menus).
"""
from __future__ import print_function

import sys

from kconfiglib import Symbol, Choice, BOOL, TRISTATE, HEX, standard_kconfig


# Python 2/3 compatibility hack
if sys.version_info[0] < 3:
    input = raw_input


def _main():
    # Earlier symbols in Kconfig files might depend on later symbols and become
    # visible if their values change. This flag is set to True if the value of
    # any symbol changes, in which case we rerun the oldconfig to check for new
    # visible symbols.
    global conf_changed

    kconf = standard_kconfig(__doc__)
    print(kconf.load_config())

    while True:
        conf_changed = False

        for node in kconf.node_iter():
            oldconfig(node)

        if not conf_changed:
            break

    print(kconf.write_config())


def oldconfig(node):
    """
    Prompts the user for a value if node.item is a visible symbol/choice with
    no user value.
    """
    # See main()
    global conf_changed

    # Only symbols and choices can be configured
    if not isinstance(node.item, (Symbol, Choice)):
        return

    # Skip symbols and choices that aren't visible
    if not node.item.visibility:
        return

    # Skip symbols and choices that don't have a prompt (at this location)
    if not node.prompt:
        return

    if isinstance(node.item, Symbol):
        sym = node.item

        # Skip symbols that already have a user value
        if sym.user_value is not None:
            return

        # Skip symbols that can only have a single value, due to selects
        if len(sym.assignable) == 1:
            return

        # Skip symbols in choices in y mode. We ask once for the entire choice
        # instead.
        if sym.choice and sym.choice.tri_value == 2:
            return

        # Loop until the user enters a valid value or enters a blank string
        # (for the default value)
        while True:
            val = input("{} ({}) [{}] ".format(
                node.prompt[0], _name_and_loc_str(sym),
                _default_value_str(sym)))

            if val == "?":
                _print_help(node)
                continue

            # Substitute a blank string with the default value the symbol
            # would get
            if not val:
                val = sym.str_value

            # Automatically add a "0x" prefix for hex symbols, like the
            # menuconfig interface does. This isn't done when loading .config
            # files, hence why set_value() doesn't do it automatically.
            if sym.type == HEX and not val.startswith(("0x", "0X")):
                val = "0x" + val

            old_str_val = sym.str_value

            # Kconfiglib itself will print a warning here if the value
            # is invalid, so we don't need to bother
            if sym.set_value(val):
                # Valid value input. We're done with this node.

                if sym.str_value != old_str_val:
                    conf_changed = True

                return

    else:
        choice = node.item

        # Skip choices that already have a visible user selection...
        if choice.user_selection and choice.user_selection.visibility == 2:
            # ...unless there are new visible symbols in the choice. (We know
            # they have y (2) visibility in that case, because m-visible
            # symbols get demoted to n-visibility in y-mode choices, and the
            # user-selected symbol had visibility y.)
            for sym in choice.syms:
                if sym is not choice.user_selection and sym.visibility and \
                   sym.user_value is None:
                    # New visible symbols in the choice
                    break
            else:
                # No new visible symbols in the choice
                return

        # Get a list of available selections. The mode of the choice limits
        # the visibility of the choice value symbols, so this will indirectly
        # skip choices in n and m mode.
        options = [sym for sym in choice.syms if sym.visibility == 2]

        if not options:
            # No y-visible choice value symbols
            return

        # Loop until the user enters a valid selection or a blank string (for
        # the default selection)
        while True:
            print("{} ({})".format(node.prompt[0], _name_and_loc_str(choice)))

            for i, sym in enumerate(options, 1):
                print("{} {}. {} ({})".format(
                    ">" if sym is choice.selection else " ",
                    i,
                    # Assume people don't define choice symbols with multiple
                    # prompts. That generates a warning anyway.
                    sym.nodes[0].prompt[0],
                    sym.name))

            sel_index = input("choice[1-{}]: ".format(len(options)))

            if sel_index == "?":
                _print_help(node)
                continue

            # Pick the default selection if the string is blank
            if not sel_index:
                choice.selection.set_value(2)
                break

            try:
                sel_index = int(sel_index)
            except ValueError:
                print("Bad index", file=sys.stderr)
                continue

            if not 1 <= sel_index <= len(options):
                print("Bad index", file=sys.stderr)
                continue

            # Valid selection

            if options[sel_index - 1].tri_value != 2:
                conf_changed = True

            options[sel_index - 1].set_value(2)
            break

        # Give all of the non-selected visible choice symbols the user value n.
        # This makes it so that the choice is no longer considered new once we
        # do additional passes, if the reason that it was considered new was
        # that it had new visible choice symbols.
        #
        # Only giving visible choice symbols the user value n means we will
        # prompt for the choice again if later user selections make more new
        # choice symbols visible, which is correct.
        for sym in choice.syms:
            if sym is not choice.user_selection and sym.visibility:
                sym.set_value(0)


def _name_and_loc_str(sc):
    # Helper for printing the name of the symbol/choice 'sc' along with the
    # location(s) in the Kconfig files where it is defined. Unnamed choices
    # return "choice" instead of the name.

    return "{}, defined at {}".format(
        sc.name or "choice",
        ", ".join("{}:{}".format(node.filename, node.linenr)
                  for node in sc.nodes))


def _print_help(node):
    print("\n" + (node.help or "No help text\n"))


def _default_value_str(sym):
    # Returns the "m/M/y" string in e.g.
    #
    #   TRISTATE_SYM prompt (TRISTATE_SYM, defined at Kconfig:9) [n/M/y]:
    #
    # For string/int/hex, returns the default value as-is.

    if sym.type in (BOOL, TRISTATE):
        return "/".join(("NMY" if sym.tri_value == tri else "nmy")[tri]
                        for tri in sym.assignable)

    # string/int/hex
    return sym.str_value


if __name__ == "__main__":
    _main()
