Append a string or a list of flags for a given package or DEPEND atom to a
    given configuration file.

    CLI Example:

    .. code-block:: bash

        salt '*' portage_config.append_to_package_conf use string="app-admin/salt ldap -libvirt"
        salt '*' portage_config.append_to_package_conf use atom="> = app-admin/salt-0.14.1" flags="['ldap', '-libvirt']"

def append_to_package_conf(conf, atom='', flags=None, string='', overwrite=False):
    '''
    Append a string or a list of flags for a given package or DEPEND atom to a
    given configuration file.

    CLI Example:

    .. code-block:: bash

        salt '*' portage_config.append_to_package_conf use string="app-admin/salt ldap -libvirt"
        salt '*' portage_config.append_to_package_conf use atom="> = app-admin/salt-0.14.1" flags="['ldap', '-libvirt']"
    '''
    if flags is None:
        flags = []
    if conf in SUPPORTED_CONFS:
        if not string:
            if '/' not in atom:
                atom = _p_to_cp(atom)
                if not atom:
                    return
            string = '{0} {1}'.format(atom, ' '.join(flags))
            new_flags = list(flags)
        else:
            atom = string.strip().split()[0]
            new_flags = [flag for flag in string.strip().split(' ') if flag][1:]
            if '/' not in atom:
                atom = _p_to_cp(atom)
                string = '{0} {1}'.format(atom, ' '.join(new_flags))
                if not atom:
                    return

        to_delete_if_empty = []
        if conf == 'accept_keywords':
            if '-~ARCH' in new_flags:
                new_flags.remove('-~ARCH')
                to_delete_if_empty.append(atom)

            if '~ARCH' in new_flags:
                new_flags.remove('~ARCH')
                append_to_package_conf(conf, string=atom, overwrite=overwrite)
                if not new_flags:
                    return

        # Next sort is just aesthetic, can be commented for a small performance
        # boost
        new_flags.sort(key=lambda x: x.lstrip('-'))

        complete_file_path = _get_config_file(conf, atom)
        pdir = os.path.dirname(complete_file_path)
        if not os.path.exists(pdir):
            os.makedirs(pdir, 0o755)

        try:
            shutil.copy(complete_file_path, complete_file_path + '.bak')
        except IOError:
            pass

        try:
            file_handler = salt.utils.files.fopen(complete_file_path, 'r+')  # pylint: disable=resource-leakage
        except IOError:
            file_handler = salt.utils.files.fopen(complete_file_path, 'w+')  # pylint: disable=resource-leakage

        new_contents = ''
        added = False

        try:
            for l in file_handler:
                l_strip = l.strip()
                if l_strip == '':
                    new_contents += '\n'
                elif l_strip[0] == '#':
                    new_contents += l
                elif l_strip.split()[0] == atom:
                    if l_strip in to_delete_if_empty:
                        continue
                    if overwrite:
                        new_contents += string.strip() + '\n'
                        added = True
                    else:
                        old_flags = [flag for flag in l_strip.split(' ') if flag][1:]
                        if conf == 'accept_keywords':
                            if not old_flags:
                                new_contents += l
                                if not new_flags:
                                    added = True
                                continue
                            elif not new_flags:
                                continue
                        merged_flags = _merge_flags(new_flags, old_flags, conf)
                        if merged_flags:
                            new_contents += '{0} {1}\n'.format(
                                atom, ' '.join(merged_flags))
                        else:
                            new_contents += '{0}\n'.format(atom)
                        added = True
                else:
                    new_contents += l
            if not added:
                new_contents += string.strip() + '\n'
        except Exception as exc:
            log.error('Failed to write to %s: %s', complete_file_path, exc)
        else:
            file_handler.seek(0)
            file_handler.truncate(len(new_contents))
            file_handler.write(new_contents)
        finally:
            file_handler.close()

        try:
            os.remove(complete_file_path + '.bak')
        except OSError:
            pass