# SPDX-License-Identifier: GPL-2.0+
# Copyright (c) 2011 The Chromium OS Authors.
#

try:
    import configparser as ConfigParser
except:
    import ConfigParser

import argparse
import os
import re

from patman import command
from patman import tools

"""Default settings per-project.

These are used by _ProjectConfigParser.  Settings names should match
the "dest" of the option parser from patman.py.
"""
_default_settings = {
    "u-boot": {},
    "linux": {
        "process_tags": "False",
        "check_patch_use_tree": "True",
    },
    "gcc": {
        "process_tags": "False",
        "add_signoff": "False",
        "check_patch": "False",
    },
}

class _ProjectConfigParser(ConfigParser.SafeConfigParser):
    """ConfigParser that handles projects.

    There are two main goals of this class:
    - Load project-specific default settings.
    - Merge general default settings/aliases with project-specific ones.

    # Sample config used for tests below...
    >>> from io import StringIO
    >>> sample_config = '''
    ... [alias]
    ... me: Peter P. <likesspiders@example.com>
    ... enemies: Evil <evil@example.com>
    ...
    ... [sm_alias]
    ... enemies: Green G. <ugly@example.com>
    ...
    ... [sm2_alias]
    ... enemies: Doc O. <pus@example.com>
    ...
    ... [settings]
    ... am_hero: True
    ... '''

    # Check to make sure that bogus project gets general alias.
    >>> config = _ProjectConfigParser("zzz")
    >>> config.readfp(StringIO(sample_config))
    >>> str(config.get("alias", "enemies"))
    'Evil <evil@example.com>'

    # Check to make sure that alias gets overridden by project.
    >>> config = _ProjectConfigParser("sm")
    >>> config.readfp(StringIO(sample_config))
    >>> str(config.get("alias", "enemies"))
    'Green G. <ugly@example.com>'

    # Check to make sure that settings get merged with project.
    >>> config = _ProjectConfigParser("linux")
    >>> config.readfp(StringIO(sample_config))
    >>> sorted((str(a), str(b)) for (a, b) in config.items("settings"))
    [('am_hero', 'True'), ('check_patch_use_tree', 'True'), ('process_tags', 'False')]

    # Check to make sure that settings works with unknown project.
    >>> config = _ProjectConfigParser("unknown")
    >>> config.readfp(StringIO(sample_config))
    >>> sorted((str(a), str(b)) for (a, b) in config.items("settings"))
    [('am_hero', 'True')]
    """
    def __init__(self, project_name):
        """Construct _ProjectConfigParser.

        In addition to standard SafeConfigParser initialization, this also loads
        project defaults.

        Args:
            project_name: The name of the project.
        """
        self._project_name = project_name
        ConfigParser.SafeConfigParser.__init__(self)

        # Update the project settings in the config based on
        # the _default_settings global.
        project_settings = "%s_settings" % project_name
        if not self.has_section(project_settings):
            self.add_section(project_settings)
        project_defaults = _default_settings.get(project_name, {})
        for setting_name, setting_value in project_defaults.items():
            self.set(project_settings, setting_name, setting_value)

    def get(self, section, option, *args, **kwargs):
        """Extend SafeConfigParser to try project_section before section.

        Args:
            See SafeConfigParser.
        Returns:
            See SafeConfigParser.
        """
        try:
            val = ConfigParser.SafeConfigParser.get(
                self, "%s_%s" % (self._project_name, section), option,
                *args, **kwargs
            )
        except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
            val = ConfigParser.SafeConfigParser.get(
                self, section, option, *args, **kwargs
            )
        return val

    def items(self, section, *args, **kwargs):
        """Extend SafeConfigParser to add project_section to section.

        Args:
            See SafeConfigParser.
        Returns:
            See SafeConfigParser.
        """
        project_items = []
        has_project_section = False
        top_items = []

        # Get items from the project section
        try:
            project_items = ConfigParser.SafeConfigParser.items(
                self, "%s_%s" % (self._project_name, section), *args, **kwargs
            )
            has_project_section = True
        except ConfigParser.NoSectionError:
            pass

        # Get top-level items
        try:
            top_items = ConfigParser.SafeConfigParser.items(
                self, section, *args, **kwargs
            )
        except ConfigParser.NoSectionError:
            # If neither section exists raise the error on...
            if not has_project_section:
                raise

        item_dict = dict(top_items)
        item_dict.update(project_items)
        return {(item, val) for item, val in item_dict.items()}

def ReadGitAliases(fname):
    """Read a git alias file. This is in the form used by git:

    alias uboot  u-boot@lists.denx.de
    alias wd     Wolfgang Denk <wd@denx.de>

    Args:
        fname: Filename to read
    """
    try:
        fd = open(fname, 'r', encoding='utf-8')
    except IOError:
        print("Warning: Cannot find alias file '%s'" % fname)
        return

    re_line = re.compile('alias\s+(\S+)\s+(.*)')
    for line in fd.readlines():
        line = line.strip()
        if not line or line[0] == '#':
            continue

        m = re_line.match(line)
        if not m:
            print("Warning: Alias file line '%s' not understood" % line)
            continue

        list = alias.get(m.group(1), [])
        for item in m.group(2).split(','):
            item = item.strip()
            if item:
                list.append(item)
        alias[m.group(1)] = list

    fd.close()

def CreatePatmanConfigFile(gitutil, config_fname):
    """Creates a config file under $(HOME)/.patman if it can't find one.

    Args:
        config_fname: Default config filename i.e., $(HOME)/.patman

    Returns:
        None
    """
    name = gitutil.get_default_user_name()
    if name == None:
        name = input("Enter name: ")

    email = gitutil.get_default_user_email()

    if email == None:
        email = input("Enter email: ")

    try:
        f = open(config_fname, 'w')
    except IOError:
        print("Couldn't create patman config file\n")
        raise

    print('''[alias]
me: %s <%s>

[bounces]
nxp = Zhikang Zhang <zhikang.zhang@nxp.com>
''' % (name, email), file=f)
    f.close();

def _UpdateDefaults(main_parser, config):
    """Update the given OptionParser defaults based on config.

    We'll walk through all of the settings from all parsers.
    For each setting we'll look for a default in the option parser.
    If it's found we'll update the option parser default.

    The idea here is that the .patman file should be able to update
    defaults but that command line flags should still have the final
    say.

    Args:
        parser: An instance of an ArgumentParser whose defaults will be
            updated.
        config: An instance of _ProjectConfigParser that we will query
            for settings.
    """
    # Find all the parsers and subparsers
    parsers = [main_parser]
    parsers += [subparser for action in main_parser._actions
                  if isinstance(action, argparse._SubParsersAction)
                  for _, subparser in action.choices.items()]

    # Collect the defaults from each parser
    defaults = {}
    parser_defaults = []
    for parser in parsers:
        pdefs = parser.parse_known_args()[0]
        parser_defaults.append(pdefs)
        defaults.update(vars(pdefs))

    # Go through the settings and collect defaults
    for name, val in config.items('settings'):
        if name in defaults:
            default_val = defaults[name]
            if isinstance(default_val, bool):
                val = config.getboolean('settings', name)
            elif isinstance(default_val, int):
                val = config.getint('settings', name)
            elif isinstance(default_val, str):
                val = config.get('settings', name)
            defaults[name] = val
        else:
            print("WARNING: Unknown setting %s" % name)

    # Set all the defaults and manually propagate them to subparsers
    main_parser.set_defaults(**defaults)
    for parser, pdefs in zip(parsers, parser_defaults):
        parser.set_defaults(**{ k: v for k, v in defaults.items()
                                    if k in pdefs })

def _ReadAliasFile(fname):
    """Read in the U-Boot git alias file if it exists.

    Args:
        fname: Filename to read.
    """
    if os.path.exists(fname):
        bad_line = None
        with open(fname, encoding='utf-8') as fd:
            linenum = 0
            for line in fd:
                linenum += 1
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                words = line.split(None, 2)
                if len(words) < 3 or words[0] != 'alias':
                    if not bad_line:
                        bad_line = "%s:%d:Invalid line '%s'" % (fname, linenum,
                                                                line)
                    continue
                alias[words[1]] = [s.strip() for s in words[2].split(',')]
        if bad_line:
            print(bad_line)

def _ReadBouncesFile(fname):
    """Read in the bounces file if it exists

    Args:
        fname: Filename to read.
    """
    if os.path.exists(fname):
        with open(fname) as fd:
            for line in fd:
                if line.startswith('#'):
                    continue
                bounces.add(line.strip())

def GetItems(config, section):
    """Get the items from a section of the config.

    Args:
        config: _ProjectConfigParser object containing settings
        section: name of section to retrieve

    Returns:
        List of (name, value) tuples for the section
    """
    try:
        return config.items(section)
    except ConfigParser.NoSectionError as e:
        return []
    except:
        raise

def Setup(gitutil, parser, project_name, config_fname=''):
    """Set up the settings module by reading config files.

    Args:
        parser:         The parser to update
        project_name:   Name of project that we're working on; we'll look
            for sections named "project_section" as well.
        config_fname:   Config filename to read ('' for default)
    """
    # First read the git alias file if available
    _ReadAliasFile('doc/git-mailrc')
    config = _ProjectConfigParser(project_name)
    if config_fname == '':
        config_fname = '%s/.patman' % os.getenv('HOME')

    if not os.path.exists(config_fname):
        print("No config file found ~/.patman\nCreating one...\n")
        CreatePatmanConfigFile(gitutil, config_fname)

    config.read(config_fname)

    for name, value in GetItems(config, 'alias'):
        alias[name] = value.split(',')

    _ReadBouncesFile('doc/bounces')
    for name, value in GetItems(config, 'bounces'):
        bounces.add(value)

    _UpdateDefaults(parser, config)

# These are the aliases we understand, indexed by alias. Each member is a list.
alias = {}
bounces = set()

if __name__ == "__main__":
    import doctest

    doctest.testmod()
