# SPDX-License-Identifier: GPL-2.0+
# Copyright 2022 Google LLC
# Written by Simon Glass <sjg@chromium.org>
#

"""Utility functions for dealing with Kconfig .confing files"""

import re

from patman import tools

RE_LINE = re.compile(r'(# )?CONFIG_([A-Z0-9_]+)(=(.*)| is not set)')
RE_CFG = re.compile(r'(~?)(CONFIG_)?([A-Z0-9_]+)(=.*)?')

def make_cfg_line(opt, adj):
    """Make a new config line for an option

    Args:
        opt (str): Option to process, without CONFIG_ prefix
        adj (str): Adjustment to make (C is config option without prefix):
             C to enable C
             ~C to disable C
             C=val to set the value of C (val must have quotes if C is
                 a string Kconfig)

    Returns:
        str: New line to use, one of:
            CONFIG_opt=y               - option is enabled
            # CONFIG_opt is not set    - option is disabled
            CONFIG_opt=val             - option is getting a new value (val is
                in quotes if this is a string)
    """
    if adj[0] == '~':
        return f'# CONFIG_{opt} is not set'
    if '=' in adj:
        return f'CONFIG_{adj}'
    return f'CONFIG_{opt}=y'

def adjust_cfg_line(line, adjust_cfg, done=None):
    """Make an adjustment to a single of line from a .config file

    This processes a .config line, producing a new line if a change for this
    CONFIG is requested in adjust_cfg

    Args:
        line (str): line to process, e.g. '# CONFIG_FRED is not set' or
            'CONFIG_FRED=y' or 'CONFIG_FRED=0x123' or 'CONFIG_FRED="fred"'
        adjust_cfg (dict of str): Changes to make to .config file before
                building:
             key: str config to change, without the CONFIG_ prefix, e.g.
                 FRED
             value: str change to make (C is config option without prefix):
                 C to enable C
                 ~C to disable C
                 C=val to set the value of C (val must have quotes if C is
                     a string Kconfig)
        done (set of set): Adds the config option to this set if it is changed
            in some way. This is used to track which ones have been processed.
            None to skip.

    Returns:
        tuple:
            str: New string for this line (maybe unchanged)
            str: Adjustment string that was used
    """
    out_line = line
    m_line = RE_LINE.match(line)
    adj = None
    if m_line:
        _, opt, _, _ = m_line.groups()
        adj = adjust_cfg.get(opt)
        if adj:
            out_line = make_cfg_line(opt, adj)
            if done is not None:
                done.add(opt)

    return out_line, adj

def adjust_cfg_lines(lines, adjust_cfg):
    """Make adjustments to a list of lines from a .config file

    Args:
        lines (list of str): List of lines to process
        adjust_cfg (dict of str): Changes to make to .config file before
                building:
             key: str config to change, without the CONFIG_ prefix, e.g.
                 FRED
             value: str change to make (C is config option without prefix):
                 C to enable C
                 ~C to disable C
                 C=val to set the value of C (val must have quotes if C is
                     a string Kconfig)

    Returns:
        list of str: New list of lines resulting from the processing
    """
    out_lines = []
    done = set()
    for line in lines:
        out_line, _ = adjust_cfg_line(line, adjust_cfg, done)
        out_lines.append(out_line)

    for opt in adjust_cfg:
        if opt not in done:
            adj = adjust_cfg.get(opt)
            out_line = make_cfg_line(opt, adj)
            out_lines.append(out_line)

    return out_lines

def adjust_cfg_file(fname, adjust_cfg):
    """Make adjustments to a .config file

    Args:
        fname (str): Filename of .config file to change
        adjust_cfg (dict of str): Changes to make to .config file before
                building:
             key: str config to change, without the CONFIG_ prefix, e.g.
                 FRED
             value: str change to make (C is config option without prefix):
                 C to enable C
                 ~C to disable C
                 C=val to set the value of C (val must have quotes if C is
                     a string Kconfig)
    """
    lines = tools.ReadFile(fname, binary=False).splitlines()
    out_lines = adjust_cfg_lines(lines, adjust_cfg)
    out = '\n'.join(out_lines) + '\n'
    tools.WriteFile(fname, out, binary=False)

def convert_list_to_dict(adjust_cfg_list):
    """Convert a list of config changes into the dict used by adjust_cfg_file()

    Args:
        adjust_cfg_list (list of str): List of changes to make to .config file
            before building. Each is one of (where C is the config option with
            or without the CONFIG_ prefix)

                C to enable C
                ~C to disable C
                C=val to set the value of C (val must have quotes if C is
                    a string Kconfig

    Returns:
        dict of str: Changes to make to .config file before building:
             key: str config to change, without the CONFIG_ prefix, e.g. FRED
             value: str change to make (C is config option without prefix):
                 C to enable C
                 ~C to disable C
                 C=val to set the value of C (val must have quotes if C is
                     a string Kconfig)

    Raises:
        ValueError: if an item in adjust_cfg_list has invalid syntax
    """
    result = {}
    for cfg in adjust_cfg_list or []:
        m_cfg = RE_CFG.match(cfg)
        if not m_cfg:
            raise ValueError(f"Invalid CONFIG adjustment '{cfg}'")
        negate, _, opt, val = m_cfg.groups()
        result[opt] = f'%s{opt}%s' % (negate or '', val or '')

    return result

def check_cfg_lines(lines, adjust_cfg):
    """Check that lines do not conflict with the requested changes

    If a line enables a CONFIG which was requested to be disabled, etc., then
    this is an error. This function finds such errors.

    Args:
        lines (list of str): List of lines to process
        adjust_cfg (dict of str): Changes to make to .config file before
                building:
             key: str config to change, without the CONFIG_ prefix, e.g.
                 FRED
             value: str change to make (C is config option without prefix):
                 C to enable C
                 ~C to disable C
                 C=val to set the value of C (val must have quotes if C is
                     a string Kconfig)

    Returns:
        list of tuple: list of errors, each a tuple:
            str: cfg adjustment requested
            str: line of the config that conflicts
    """
    bad = []
    done = set()
    for line in lines:
        out_line, adj = adjust_cfg_line(line, adjust_cfg, done)
        if out_line != line:
            bad.append([adj, line])

    for opt in adjust_cfg:
        if opt not in done:
            adj = adjust_cfg.get(opt)
            out_line = make_cfg_line(opt, adj)
            bad.append([adj, f'Missing expected line: {out_line}'])

    return bad

def check_cfg_file(fname, adjust_cfg):
    """Check that a config file has been adjusted according to adjust_cfg

    Args:
        fname (str): Filename of .config file to change
        adjust_cfg (dict of str): Changes to make to .config file before
                building:
             key: str config to change, without the CONFIG_ prefix, e.g.
                 FRED
             value: str change to make (C is config option without prefix):
                 C to enable C
                 ~C to disable C
                 C=val to set the value of C (val must have quotes if C is
                     a string Kconfig)

    Returns:
        str: None if OK, else an error string listing the problems
    """
    lines = tools.ReadFile(fname, binary=False).splitlines()
    bad_cfgs = check_cfg_lines(lines, adjust_cfg)
    if bad_cfgs:
        out = [f'{cfg:20}  {line}' for cfg, line in bad_cfgs]
        content = '\\n'.join(out)
        return f'''
Some CONFIG adjustments did not take effect. This may be because
the request CONFIGs do not exist or conflict with others.

Failed adjustments:

{content}
'''
    return None
