Modify one or more values for a repo. If the repo does not exist, it will
    be created, so long as the following values are specified:

    repo or alias
        alias by which Zypper refers to the repo

    url, mirrorlist or baseurl
        the URL for Zypper to reference

    enabled
        Enable or disable (True or False) repository,
        but do not remove if disabled.

    refresh
        Enable or disable (True or False) auto-refresh of the repository.

    cache
        Enable or disable (True or False) RPM files caching.

    gpgcheck
        Enable or disable (True or False) GPG check for this repository.

    gpgautoimport : False
        If set to True, automatically trust and import public GPG key for
        the repository.

    root
        operate on a different root directory.

    Key/Value pairs may also be removed from a repo's configuration by setting
    a key to a blank value. Bear in mind that a name cannot be deleted, and a
    URL can only be deleted if a ``mirrorlist`` is specified (or vice versa).

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.mod_repo alias alias=new_alias
        salt '*' pkg.mod_repo alias url= mirrorlist=http://host.com/

def mod_repo(repo, **kwargs):
    '''
    Modify one or more values for a repo. If the repo does not exist, it will
    be created, so long as the following values are specified:

    repo or alias
        alias by which Zypper refers to the repo

    url, mirrorlist or baseurl
        the URL for Zypper to reference

    enabled
        Enable or disable (True or False) repository,
        but do not remove if disabled.

    refresh
        Enable or disable (True or False) auto-refresh of the repository.

    cache
        Enable or disable (True or False) RPM files caching.

    gpgcheck
        Enable or disable (True or False) GPG check for this repository.

    gpgautoimport : False
        If set to True, automatically trust and import public GPG key for
        the repository.

    root
        operate on a different root directory.

    Key/Value pairs may also be removed from a repo's configuration by setting
    a key to a blank value. Bear in mind that a name cannot be deleted, and a
    URL can only be deleted if a ``mirrorlist`` is specified (or vice versa).

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.mod_repo alias alias=new_alias
        salt '*' pkg.mod_repo alias url= mirrorlist=http://host.com/
    '''

    root = kwargs.get('root') or None
    repos_cfg = _get_configured_repos(root=root)
    added = False

    # An attempt to add new one?
    if repo not in repos_cfg.sections():
        url = kwargs.get('url', kwargs.get('mirrorlist', kwargs.get('baseurl')))
        if not url:
            raise CommandExecutionError(
                'Repository \'{0}\' not found, and neither \'baseurl\' nor '
                '\'mirrorlist\' was specified'.format(repo)
            )

        if not _urlparse(url).scheme:
            raise CommandExecutionError(
                'Repository \'{0}\' not found and URL for baseurl/mirrorlist '
                'is malformed'.format(repo)
            )

        # Is there already such repo under different alias?
        for alias in repos_cfg.sections():
            repo_meta = _get_repo_info(alias, repos_cfg=repos_cfg, root=root)

            # Complete user URL, in case it is not
            new_url = _urlparse(url)
            if not new_url.path:
                new_url = _urlparse.ParseResult(scheme=new_url.scheme,  # pylint: disable=E1123
                                                netloc=new_url.netloc,
                                                path='/',
                                                params=new_url.params,
                                                query=new_url.query,
                                                fragment=new_url.fragment)
            base_url = _urlparse(repo_meta['baseurl'])

            if new_url == base_url:
                raise CommandExecutionError(
                    'Repository \'{0}\' already exists as \'{1}\'.'.format(
                        repo,
                        alias
                    )
                )

        # Add new repo
        __zypper__(root=root).xml.call('ar', url, repo)

        # Verify the repository has been added
        repos_cfg = _get_configured_repos(root=root)
        if repo not in repos_cfg.sections():
            raise CommandExecutionError(
                'Failed add new repository \'{0}\' for unspecified reason. '
                'Please check zypper logs.'.format(repo))
        added = True

    repo_info = _get_repo_info(repo, root=root)
    if (
        not added and 'baseurl' in kwargs and
        not (kwargs['baseurl'] == repo_info['baseurl'])
    ):
        # Note: zypper does not support changing the baseurl
        # we need to remove the repository and add it again with the new baseurl
        repo_info.update(kwargs)
        repo_info.setdefault('cache', False)
        del_repo(repo, root=root)
        return mod_repo(repo, root=root, **repo_info)

    # Modify added or existing repo according to the options
    cmd_opt = []
    global_cmd_opt = []
    call_refresh = False

    if 'enabled' in kwargs:
        cmd_opt.append(kwargs['enabled'] and '--enable' or '--disable')

    if 'refresh' in kwargs:
        cmd_opt.append(kwargs['refresh'] and '--refresh' or '--no-refresh')

    if 'cache' in kwargs:
        cmd_opt.append(
            kwargs['cache'] and '--keep-packages' or '--no-keep-packages'
        )

    if 'gpgcheck' in kwargs:
        cmd_opt.append(kwargs['gpgcheck'] and '--gpgcheck' or '--no-gpgcheck')

    if 'priority' in kwargs:
        cmd_opt.append("--priority={0}".format(kwargs.get('priority', DEFAULT_PRIORITY)))

    if 'humanname' in kwargs:
        cmd_opt.append("--name='{0}'".format(kwargs.get('humanname')))

    if kwargs.get('gpgautoimport') is True:
        global_cmd_opt.append('--gpg-auto-import-keys')
        call_refresh = True

    if cmd_opt:
        cmd_opt = global_cmd_opt + ['mr'] + cmd_opt + [repo]
        __zypper__(root=root).refreshable.xml.call(*cmd_opt)

    comment = None
    if call_refresh:
        # when used with "zypper ar --refresh" or "zypper mr --refresh"
        # --gpg-auto-import-keys is not doing anything
        # so we need to specifically refresh here with --gpg-auto-import-keys
        refresh_opts = global_cmd_opt + ['refresh'] + [repo]
        __zypper__(root=root).xml.call(*refresh_opts)
    elif not added and not cmd_opt:
        comment = 'Specified arguments did not result in modification of repo'

    repo = get_repo(repo, root=root)
    if comment:
        repo['comment'] = comment

    return repo