def create_xml_from_ini(self, ini_filepath, ini_content):
        """
        Creates group.xml file from INI file. All tags are replaced by function
        update_value_list. Function also checks whether check script fulfills
        all criteria

        @param {str} ini_filepath - real path of ini file
        @param {dict} ini_content - options and values from ini file:
            {option1: value, option2: value, ...}
        @throws {IOError}
        """
        self.select_rules.append(xml_tags.SELECT_TAG)
        update_fnc = {
            'config_file': self.fnc_config_file,
            'check_script': self.fnc_check_script,
            'check_description': self.fnc_check_description,
            'solution': self.fnc_solution_text,
            'content_title': self.update_text,
            'content_description': self.update_text,
        }
        ModuleHelper.check_required_fields(ini_filepath, ini_content)
        self.mh = ModuleHelper(os.path.dirname(ini_filepath))

        self.update_values_list(self.rule, "{rule_tag}",
                                ''.join(xml_tags.RULE_SECTION))
        value_tag, check_export_tag = self.add_value_tag()
        self.update_values_list(self.rule, "{check_export}",
                                ''.join(check_export_tag))
        self.update_values_list(self.rule, "{group_value}",
                                ''.join(value_tag))

        for k, function in iter(update_fnc.items()):
            try:
                function(ini_content, k)
            except IOError as e:
                err_msg = "Invalid value of the field '%s' in INI file" \
                          " '%s'\n'%s': %s\n" % (k, ini_filepath,
                                                 ini_content[k], e.strerror)
                raise IOError(err_msg)

        self.update_values_list(
            self.rule, '{group_title}',
            html_escape(ini_content['content_title'])
        )
        if 'mode' not in ini_content:
            self.fnc_update_mode('migrate, upgrade')
        else:
            self.fnc_update_mode(ini_content['mode'])
    def create_xml_from_ini(self, ini_filepath, ini_content):
        """
        Creates group.xml file from INI file. All tags are replaced by function
        update_value_list. Function also checks whether check script fulfills
        all criteria

        @param {str} ini_filepath - real path of ini file
        @param {dict} ini_content - options and values from ini file:
            {option1: value, option2: value, ...}
        @throws {IOError}
        """
        self.select_rules.append(xml_tags.SELECT_TAG)
        update_fnc = {
            'config_file': self.fnc_config_file,
            'check_script': self.fnc_check_script,
            'check_description': self.fnc_check_description,
            'solution': self.fnc_solution_text,
            'content_title': self.update_text,
            'content_description': self.update_text,
        }
        ModuleHelper.check_required_fields(ini_filepath, ini_content)
        self.mh = ModuleHelper(os.path.dirname(ini_filepath))

        self.update_values_list(self.rule, "{rule_tag}",
                                ''.join(xml_tags.RULE_SECTION))
        value_tag, check_export_tag = self.add_value_tag()
        self.update_values_list(self.rule, "{check_export}",
                                ''.join(check_export_tag))
        self.update_values_list(self.rule, "{group_value}", ''.join(value_tag))

        for k, function in iter(update_fnc.items()):
            try:
                function(ini_content, k)
            except IOError as e:
                err_msg = "Invalid value of the field '%s' in INI file" \
                          " '%s'\n'%s': %s\n" % (k, ini_filepath,
                                                 ini_content[k], e.strerror)
                raise IOError(err_msg)

        self.update_values_list(self.rule, '{group_title}',
                                html_escape(ini_content['content_title']))
        if 'mode' not in ini_content:
            self.fnc_update_mode('migrate, upgrade')
        else:
            self.fnc_update_mode(ini_content['mode'])
    def create_xml_from_ini(self, main):
        """
        The function creates group.xml file from INI file.
        All tag are replaced by function update_value_list

        Function also checks whether check script full fills all criteria
        """
        self.select_rules.append(xml_tags.SELECT_TAG)
        update_fnc = {
            'config_file': self.fnc_config_file,
            'check_script': self.fnc_check_script,
            'check_description': self.fnc_check_description,
            'solution': self.fnc_solution_text,
            'applies_to': self.dummy_fnc,
            'binary_req': self.dummy_fnc,
            'content_title': self.update_text,
            'content_description': self.update_text,
        }
        for key in self.keys:
            if 'check_script' not in key:
                raise MissingTagsIniFileError
            if 'solution' not in key:
                raise MissingTagsIniFileError
            self.mh = ModuleHelper(os.path.dirname(main), key['check_script'],
                                   key['solution'])
            self.mh.check_recommended_fields(key)
            # Add solution text into value
            if 'solution' in key:
                xml_tags.DIC_VALUES['solution_file'] = key['solution']
            else:
                xml_tags.DIC_VALUES['solution_file'] = 'solution.txt'

            # Add flag where will be shown content if in admin part or in user part
            if 'result_part' in key:
                xml_tags.DIC_VALUES['result_part'] = key['result_part']
            else:
                xml_tags.DIC_VALUES['result_part'] = 'admin'

            self.update_values_list(self.rule, "{rule_tag}",
                                    ''.join(xml_tags.RULE_SECTION))
            value_tag, check_export_tag = self.add_value_tag()
            self.update_values_list(self.rule, "{check_export}",
                                    ''.join(check_export_tag))
            self.update_values_list(self.rule, "{group_value}",
                                    ''.join(value_tag))

            try:
                for k, function in six.iteritems(update_fnc):
                    try:
                        function(key, k)
                    except IOError as e:
                        e_title = "Wrong value for tag '%s' in INI file '%s'\n" % (
                            k, main)
                        e_msg = "'%s': %s" % (key[k], e.strerror)
                        MessageHelper.print_error_msg(title=e_title, msg=e_msg)
                        raise MissingTagsIniFileError
            except MissingTagsIniFileError:
                title = "Following tag '%s' is missing in INI File %s\n" % (
                    k, main)
                MessageHelper.print_error_msg(title=title)
                raise MissingTagsIniFileError

            self.update_values_list(self.rule, '{group_title}',
                                    html_escape_string(key['content_title']))
            try:
                if 'mode' not in key:
                    self.fnc_update_mode(key['check_script'],
                                         'migrate, upgrade')
                else:
                    self.fnc_update_mode(key['check_script'], key['mode'])
            except KeyError:
                pass
class XmlUtils(object):
    """Class generate a XML from xml_tags and loaded INI file"""
    def __init__(self, dir_name, ini_files):
        self.keys = {}
        self.select_rules = []
        self.rule = []
        self.dirname = dir_name
        self.ini_files = ini_files
        self._test_init_file()
        self.mh = None

    def _test_init_file(self):
        test_dict = copy.deepcopy(self.ini_files)
        allowed_tags = [
            'check_script', 'content_description', 'content_title',
            'applies_to', 'author', 'binary_req', 'solution', 'bugzilla',
            'config_file', 'group_title', 'mode', 'requires', 'solution_type'
        ]
        for ini, content in six.iteritems(test_dict):
            content_dict = content[0]
            for tag in allowed_tags:
                if tag in content_dict:
                    del content_dict[tag]
            if content_dict:
                tags = ','.join(six.iterkeys(content_dict))
                MessageHelper.print_error_msg(
                    title="The tag '%s' is not allowed in INI file %s." %
                    (tags, ini),
                    msg="\nAllowed tags for contents are %s" %
                    ','.join(allowed_tags),
                    level=' WARNING ')

    def update_files(self, file_name, content):
        """Function updates file_name <migrate or update> according to INI file."""
        """
        :param file_name: specified in INI file like mode: upgrade, migrate
        :param content: name of the content like xccdf_rule_...
        :return: Nothing
        """
        path_name = os.path.join(settings.UPGRADE_PATH, file_name)
        lines = []
        if os.path.exists(path_name):
            lines = FileHelper.get_file_content(path_name, 'rb', method=True)
        test_content = [x.strip() for x in lines if content in x.strip()]
        if not test_content:
            lines.append(content + '\n')
            FileHelper.write_to_file(path_name, 'wb', lines)

    def _update_check_description(self, filename):
        new_text = []
        lines = FileHelper.get_file_content(
            os.path.join(self.dirname, filename), "rb", True)

        bold = '<xhtml:b>{0}</xhtml:b>'
        br = '<xhtml:br/>'
        table_begin = '<xhtml:table>'
        table_end = '</xhtml:table>'
        table_header = '<xhtml:tr><xhtml:th>Result</xhtml:th><xhtml:th>Description</xhtml:th></xhtml:tr>'
        table_row = '<xhtml:tr><xhtml:td>{0}</xhtml:td><xhtml:td>{1}</xhtml:td></xhtml:tr>'
        new_text.append(br + br + '\n' + bold.format('Details:') + br)
        results = False
        for line in lines:
            if '=' in line:
                if not results:
                    new_text.append(bold.format('Expected results:') + br)
                    new_text.append(table_begin + '\n' + table_header)
                    results = True
                try:
                    exp_results = line.strip().split('=')
                    new_text.append(
                        table_row.format(exp_results[0], exp_results[1]) +
                        '\n')
                except IndexError:
                    pass
            else:
                new_text.append(line.rstrip() + br)
        if results:
            new_text.append(table_end + '\n')

        return '\n'.join(new_text)

    def update_values_list(self, section, search_exp, replace_exp):
        """
        The function replaces tags taken from INI files.
        Tags are mentioned in xml_tags.py
        """
        forbidden_empty = ["{scap_name}", "{main_dir}"]
        if search_exp == "{content_description}":
            replace_exp = replace_exp.rstrip()
        elif search_exp == "{check_description}":
            replace_exp = '\n' + replace_exp + '\n'
        elif search_exp == "{config_file}":
            new_text = ""
            for lines in replace_exp.split(','):
                new_text = new_text + "<xhtml:li>" + lines.strip(
                ) + "</xhtml:li>"
            replace_exp = new_text.rstrip()
        elif search_exp == "{solution}":
            new_text = FileHelper.get_file_content(
                os.path.join(self.dirname, replace_exp), "rb", True)
            # we does not need interpreter for fix script
            # in XML therefore skip first line
            replace_exp = ''.join(new_text[1:])
        elif search_exp == "{solution_text}":
            new_text = "_" + '_'.join(get_full_xml_tag(self.dirname))\
                       + "_SOLUTION_MSG_" + replace_exp.upper()
            replace_exp = new_text
        if replace_exp == '' and search_exp in forbidden_empty:
            MessageHelper.print_error_msg(
                title="Disapproved empty replacement for tag '%s'" %
                search_exp)
            raise EmptyTagIniFileError

        for cnt, line in enumerate(section):
            if search_exp in line:
                section[cnt] = line.replace(search_exp, replace_exp)

    def add_value_tag(self):
        """The function adds VALUE tag in group.xml file"""
        value_tag = []
        check_export_tag = list()
        check_export_tag.append(xml_tags.RULE_SECTION_VALUE_IMPORT)
        for key, val in xml_tags.DIC_VALUES.items():
            value_tag.append(xml_tags.VALUE)
            if key == 'current_directory':
                val = '/'.join(get_full_xml_tag(self.dirname))
                val = 'SCENARIO/' + val
            if key == 'module_path':
                val = '_'.join(get_full_xml_tag(self.dirname))
            self.update_values_list(value_tag, "{value_name}", val)
            self.update_values_list(value_tag, "{val}", key.lower())
            check_export_tag.append(xml_tags.RULE_SECTION_VALUE)
            self.update_values_list(check_export_tag, "{value_name_upper}",
                                    key.upper())
            self.update_values_list(check_export_tag, "{val}", key.lower())
        for key, val in xml_tags.GLOBAL_DIC_VALUES.items():
            check_export_tag.append(xml_tags.RULE_SECTION_VALUE_GLOBAL)
            self.update_values_list(check_export_tag, "{value_name_upper}",
                                    key.upper())
            self.update_values_list(check_export_tag, "{value_name}", key)

        return value_tag, check_export_tag

    def solution_modification(self, key):
        """Function handles a solution text or scripts"""
        fix_tag = []
        for k in key['solution'].split(','):
            self.mh.check_scripts('solution')
            script_type = FileHelper.get_script_type(
                self.mh.get_full_path_name_solution())
            if script_type == "txt":
                fix_tag.append(xml_tags.FIX_TEXT)
            else:
                fix_tag.append(xml_tags.FIX)
            if 'solution_type' in key:
                solution_type = key['solution_type']
            else:
                solution_type = "text"
            self.update_values_list(fix_tag, "{solution_text}", solution_type)
            self.update_values_list(fix_tag, "{solution}", k.strip())
            self.update_values_list(fix_tag, "{script_type}", script_type)
        self.update_values_list(self.rule, '{fix}', ''.join(fix_tag))

    def check_script_modification(self, key, k):
        """Function checks a check script"""
        self.mh.check_scripts(k)
        check_func = {
            'log_': [
                'log_slight_risk', 'log_medium_risk', 'log_high_risk',
                'log_extreme_risk', 'log_info', 'log_error', 'log_warning'
            ],
            'exit_': [
                'exit_error', 'exit_fail', 'exit_fixed', 'exit_not_applicable',
                'exit_pass', 'exit_informational'
            ]
        }
        for check in check_func:
            self.mh.check_inplace_risk(prefix=check,
                                       check_func=check_func[check])
        self.update_values_list(self.rule, "{scap_name}", key[k].split('.')[0])
        requirements = {
            'applies_to': 'check_applies',
            'binary_req': 'check_bin',
            'requires': 'check_rpm'
        }
        updates = dict()
        for req in requirements:
            if req in key:
                updates[requirements[req]] = key[req]
        if 'author' in key:
            author = key['author']
        else:
            author = None
        self.mh.update_check_script(updates, author=author)
        self.update_values_list(self.rule, "{" + k + "}", key[k])

    def prepare_sections(self):
        """The function prepares all tags needed for generation group.xml file."""
        for main, self.keys in self.ini_files.items():
            if main.endswith("group.ini"):
                self.rule.append(xml_tags.GROUP_INI)
                for k in self.keys:
                    self.update_values_list(self.rule, '{group_title}',
                                            k['group_title'])
                    self.update_values_list(self.rule, '{group_value}', "")
            else:
                self.rule.append(xml_tags.CONTENT_INI)
                self.create_xml_from_ini(main)
                self.update_values_list(self.rule, "{select_rules}",
                                        ' '.join(self.select_rules))
            xml_tag = "{main_dir}"
            self.update_values_list(self.rule, xml_tag,
                                    '_'.join(get_full_xml_tag(self.dirname)))
        return self.rule

    def fnc_config_file(self, key, name):
        """Function updates a config file."""
        if name in key and key[name] is not None:
            self.update_values_list(self.rule, "{config_section}",
                                    xml_tags.CONFIG_SECTION)
            self.update_values_list(self.rule, "{config_file}",
                                    key['config_file'])
        else:
            self.update_values_list(self.rule, "{config_section}", "")

    def fnc_check_script(self, key, name):
        """ Function updates a check_script """
        if name in key:
            self.check_script_modification(key, name)
            self.update_values_list(self.select_rules, "{scap_name}",
                                    key[name].split('.')[0])

    def fnc_check_description(self, key, name):
        """ Function updates a check_description """
        if name in key and key[name] is not None:
            escaped_text = self._update_check_description(key[name])
            self.update_values_list(self.rule, "{check_description}",
                                    escaped_text)
        else:
            self.update_values_list(self.rule, "{check_description}", "")

    def fnc_solution_text(self, key, name):
        """Function updates a solution text."""
        if name in key:
            self.solution_modification(key)
        else:
            self.update_values_list(self.rule, "{fix}", xml_tags.FIX_TEXT)
            self.update_values_list(self.rule, "{solution_text}", "text")
            self.update_values_list(
                self.rule, "{platform_id}",
                SystemIdentification.get_assessment_version(self.dirname)[1])

    def fnc_update_mode(self, key, name):
        """
        Function update <upgrade_path>/<migrate.conf|update.conf> files
        migrate_xccdf_path
        :param key:
        :param name:
        :return:
        """

        content = "{rule}{main_dir}_{name}".format(
            rule=xml_tags.TAG_RULE,
            main_dir='_'.join(get_full_xml_tag(self.dirname)),
            name=key.split('.')[0])
        if not name:
            self.update_files('migrate', content)
            self.update_files('upgrade', content)
        for x in name.split(','):
            self.update_files(x.strip(), content)

    def dummy_fnc(self, key, name):
        """Function is only dummy."""
        pass

    def update_text(self, key, name):
        """Function updates a text."""
        try:
            if key[name] is not None:
                # escape values so they can be loaded as XMLs
                escaped_text = html_escape_string(key[name])
                self.update_values_list(self.rule, "{" + name + "}",
                                        escaped_text)
        except KeyError:
            raise MissingTagsIniFileError

    def create_xml_from_ini(self, main):
        """
        The function creates group.xml file from INI file.
        All tag are replaced by function update_value_list

        Function also checks whether check script full fills all criteria
        """
        self.select_rules.append(xml_tags.SELECT_TAG)
        update_fnc = {
            'config_file': self.fnc_config_file,
            'check_script': self.fnc_check_script,
            'check_description': self.fnc_check_description,
            'solution': self.fnc_solution_text,
            'applies_to': self.dummy_fnc,
            'binary_req': self.dummy_fnc,
            'content_title': self.update_text,
            'content_description': self.update_text,
        }
        for key in self.keys:
            if 'check_script' not in key:
                raise MissingTagsIniFileError
            if 'solution' not in key:
                raise MissingTagsIniFileError
            self.mh = ModuleHelper(os.path.dirname(main), key['check_script'],
                                   key['solution'])
            self.mh.check_recommended_fields(key)
            # Add solution text into value
            if 'solution' in key:
                xml_tags.DIC_VALUES['solution_file'] = key['solution']
            else:
                xml_tags.DIC_VALUES['solution_file'] = 'solution.txt'

            # Add flag where will be shown content if in admin part or in user part
            if 'result_part' in key:
                xml_tags.DIC_VALUES['result_part'] = key['result_part']
            else:
                xml_tags.DIC_VALUES['result_part'] = 'admin'

            self.update_values_list(self.rule, "{rule_tag}",
                                    ''.join(xml_tags.RULE_SECTION))
            value_tag, check_export_tag = self.add_value_tag()
            self.update_values_list(self.rule, "{check_export}",
                                    ''.join(check_export_tag))
            self.update_values_list(self.rule, "{group_value}",
                                    ''.join(value_tag))

            try:
                for k, function in six.iteritems(update_fnc):
                    try:
                        function(key, k)
                    except IOError as e:
                        e_title = "Wrong value for tag '%s' in INI file '%s'\n" % (
                            k, main)
                        e_msg = "'%s': %s" % (key[k], e.strerror)
                        MessageHelper.print_error_msg(title=e_title, msg=e_msg)
                        raise MissingTagsIniFileError
            except MissingTagsIniFileError:
                title = "Following tag '%s' is missing in INI File %s\n" % (
                    k, main)
                MessageHelper.print_error_msg(title=title)
                raise MissingTagsIniFileError

            self.update_values_list(self.rule, '{group_title}',
                                    html_escape_string(key['content_title']))
            try:
                if 'mode' not in key:
                    self.fnc_update_mode(key['check_script'],
                                         'migrate, upgrade')
                else:
                    self.fnc_update_mode(key['check_script'], key['mode'])
            except KeyError:
                pass
    def create_xml_from_ini(self, main):
        """
        The function creates group.xml file from INI file.
        All tag are replaced by function update_value_list

        Function also checks whether check script full fills all criteria
        """
        self.select_rules.append(xml_tags.SELECT_TAG)
        update_fnc = {
            'config_file': self.fnc_config_file,
            'check_script': self.fnc_check_script,
            'check_description': self.fnc_check_description,
            'solution': self.fnc_solution_text,
            'applies_to': self.dummy_fnc,
            'binary_req': self.dummy_fnc,
            'content_title': self.update_text,
            'content_description': self.update_text,
        }
        for key in self.keys:
            if 'check_script' not in key:
                raise MissingTagsIniFileError
            if 'solution' not in key:
                raise MissingTagsIniFileError
            self.mh = ModuleHelper(os.path.dirname(main), key['check_script'], key['solution'])
            self.mh.check_recommended_fields(key)
            # Add solution text into value
            if 'solution' in key:
                xml_tags.DIC_VALUES['solution_file'] = key['solution']
            else:
                xml_tags.DIC_VALUES['solution_file'] = 'solution.txt'

            # Add flag where will be shown content if in admin part or in user part
            if 'result_part' in key:
                xml_tags.DIC_VALUES['result_part'] = key['result_part']
            else:
                xml_tags.DIC_VALUES['result_part'] = 'admin'

            self.update_values_list(self.rule, "{rule_tag}", ''.join(xml_tags.RULE_SECTION))
            value_tag, check_export_tag = self.add_value_tag()
            self.update_values_list(self.rule, "{check_export}", ''.join(check_export_tag))
            self.update_values_list(self.rule, "{group_value}", ''.join(value_tag))

            try:
                for k, function in six.iteritems(update_fnc):
                    try:
                        function(key, k)
                    except IOError as e:
                        e_title = "Wrong value for tag '%s' in INI file '%s'\n" % (k, main)
                        e_msg = "'%s': %s" % (key[k], e.strerror)
                        MessageHelper.print_error_msg(title=e_title, msg=e_msg)
                        raise MissingTagsIniFileError
            except MissingTagsIniFileError:
                title = "Following tag '%s' is missing in INI File %s\n" % (k, main)
                MessageHelper.print_error_msg(title=title)
                raise MissingTagsIniFileError

            self.update_values_list(self.rule, '{group_title}', html_escape_string(key['content_title']))
            try:
                if 'mode' not in key:
                    self.fnc_update_mode(key['check_script'], 'migrate, upgrade')
                else:
                    self.fnc_update_mode(key['check_script'], key['mode'])
            except KeyError:
                pass
class XmlUtils(object):
    """Class generate a XML from xml_tags and loaded INI file"""
    def __init__(self, dir_name, ini_files):
        self.keys = {}
        self.select_rules = []
        self.rule = []
        self.dirname = dir_name
        self.ini_files = ini_files
        self._test_init_file()
        self.mh = None

    def _test_init_file(self):
        test_dict = copy.deepcopy(self.ini_files)
        allowed_tags = ['check_script', 'content_description', 'content_title', 'applies_to',
                        'author', 'binary_req', 'solution', 'bugzilla', 'config_file',
                        'group_title', 'mode', 'requires', 'solution_type']
        for ini, content in six.iteritems(test_dict):
            content_dict = content[0]
            for tag in allowed_tags:
                if tag in content_dict:
                    del content_dict[tag]
            if content_dict:
                tags = ','. join(six.iterkeys(content_dict))
                MessageHelper.print_error_msg(title="The tag '%s' is not allowed in INI file %s." % (tags, ini),
                                              msg="\nAllowed tags for contents are %s" % ','.join(allowed_tags),
                                              level=' WARNING ')

    def update_files(self, file_name, content):
        """Function updates file_name <migrate or update> according to INI file."""

        """
        :param file_name: specified in INI file like mode: upgrade, migrate
        :param content: name of the content like xccdf_rule_...
        :return: Nothing
        """
        path_name = os.path.join(settings.UPGRADE_PATH, file_name)
        lines = []
        if os.path.exists(path_name):
            lines = FileHelper.get_file_content(path_name, 'rb', method=True)
        test_content = [x.strip() for x in lines if content in x.strip()]
        if not test_content:
            lines.append(content + '\n')
            FileHelper.write_to_file(path_name, 'wb', lines)

    def _update_check_description(self, filename):
        new_text = []
        lines = FileHelper.get_file_content(os.path.join(self.dirname, filename), "rb", True)

        bold = '<xhtml:b>{0}</xhtml:b>'
        br = '<xhtml:br/>'
        table_begin = '<xhtml:table>'
        table_end = '</xhtml:table>'
        table_header = '<xhtml:tr><xhtml:th>Result</xhtml:th><xhtml:th>Description</xhtml:th></xhtml:tr>'
        table_row = '<xhtml:tr><xhtml:td>{0}</xhtml:td><xhtml:td>{1}</xhtml:td></xhtml:tr>'
        new_text.append(br + br + '\n' + bold.format('Details:') + br)
        results = False
        for line in lines:
            if '=' in line:
                if not results:
                    new_text.append(bold.format('Expected results:') + br)
                    new_text.append(table_begin + '\n' + table_header)
                    results = True
                try:
                    exp_results = line.strip().split('=')
                    new_text.append(table_row.format(exp_results[0], exp_results[1]) + '\n')
                except IndexError:
                    pass
            else:
                new_text.append(line.rstrip() + br)
        if results:
            new_text.append(table_end + '\n')

        return '\n'.join(new_text)

    def update_values_list(self, section, search_exp, replace_exp):
        """
        The function replaces tags taken from INI files.
        Tags are mentioned in xml_tags.py
        """
        forbidden_empty = ["{scap_name}", "{main_dir}"]
        if search_exp == "{content_description}":
            replace_exp = replace_exp.rstrip()
        elif search_exp == "{check_description}":
            replace_exp = '\n' + replace_exp + '\n'
        elif search_exp == "{config_file}":
            new_text = ""
            for lines in replace_exp.split(','):
                new_text = new_text+"<xhtml:li>"+lines.strip()+"</xhtml:li>"
            replace_exp = new_text.rstrip()
        elif search_exp == "{solution}":
            new_text = FileHelper.get_file_content(os.path.join(self.dirname, replace_exp), "rb", True)
            # we does not need interpreter for fix script
            # in XML therefore skip first line
            replace_exp = ''.join(new_text[1:])
        elif search_exp == "{solution_text}":
            new_text = "_" + '_'.join(get_full_xml_tag(self.dirname))\
                       + "_SOLUTION_MSG_" + replace_exp.upper()
            replace_exp = new_text
        if replace_exp == '' and search_exp in forbidden_empty:
            MessageHelper.print_error_msg(title="Disapproved empty replacement for tag '%s'" % search_exp)
            raise EmptyTagIniFileError

        for cnt, line in enumerate(section):
            if search_exp in line:
                section[cnt] = line.replace(search_exp, replace_exp)

    def add_value_tag(self):
        """The function adds VALUE tag in group.xml file"""
        value_tag = []
        check_export_tag = list()
        check_export_tag.append(xml_tags.RULE_SECTION_VALUE_IMPORT)
        for key, val in xml_tags.DIC_VALUES.items():
            value_tag.append(xml_tags.VALUE)
            if key == 'current_directory':
                val = '/'.join(get_full_xml_tag(self.dirname))
                val = 'SCENARIO/' + val
            if key == 'module_path':
                val = '_'.join(get_full_xml_tag(self.dirname))
            self.update_values_list(value_tag, "{value_name}", val)
            self.update_values_list(value_tag, "{val}", key.lower())
            check_export_tag.append(xml_tags.RULE_SECTION_VALUE)
            self.update_values_list(check_export_tag, "{value_name_upper}", key.upper())
            self.update_values_list(check_export_tag, "{val}", key.lower())
        for key, val in xml_tags.GLOBAL_DIC_VALUES.items():
            check_export_tag.append(xml_tags.RULE_SECTION_VALUE_GLOBAL)
            self.update_values_list(check_export_tag, "{value_name_upper}", key.upper())
            self.update_values_list(check_export_tag, "{value_name}", key)

        return value_tag, check_export_tag

    def solution_modification(self, key):
        """Function handles a solution text or scripts"""
        fix_tag = []
        for k in key['solution'].split(','):
            self.mh.check_scripts('solution')
            script_type = FileHelper.get_script_type(self.mh.get_full_path_name_solution())
            if script_type == "txt":
                fix_tag.append(xml_tags.FIX_TEXT)
            else:
                fix_tag.append(xml_tags.FIX)
            if 'solution_type' in key:
                solution_type = key['solution_type']
            else:
                solution_type = "text"
            self.update_values_list(fix_tag, "{solution_text}", solution_type)
            self.update_values_list(fix_tag, "{solution}", k.strip())
            self.update_values_list(fix_tag, "{script_type}", script_type)
        self.update_values_list(self.rule, '{fix}', ''.join(fix_tag))

    def check_script_modification(self, key, k):
        """Function checks a check script"""
        self.mh.check_scripts(k)
        check_func = {'log_': ['log_slight_risk',
                               'log_medium_risk', 'log_high_risk',
                               'log_extreme_risk', 'log_info',
                               'log_error', 'log_warning'],
                      'exit_': ['exit_error', 'exit_fail',
                                'exit_fixed', 'exit_not_applicable',
                                'exit_pass', 'exit_informational']
                      }
        for check in check_func:
            self.mh.check_inplace_risk(prefix=check, check_func=check_func[check])
        self.update_values_list(self.rule, "{scap_name}", key[k].split('.')[0])
        requirements = {'applies_to': 'check_applies',
                        'binary_req': 'check_bin',
                        'requires': 'check_rpm'}
        updates = dict()
        for req in requirements:
            if req in key:
                updates[requirements[req]] = key[req]
        if 'author' in key:
            author = key['author']
        else:
            author = None
        self.mh.update_check_script(updates, author=author)
        self.update_values_list(self.rule, "{"+k+"}", key[k])

    def prepare_sections(self):
        """The function prepares all tags needed for generation group.xml file."""
        for main, self.keys in self.ini_files.items():
            if main.endswith("group.ini"):
                self.rule.append(xml_tags.GROUP_INI)
                for k in self.keys:
                    self.update_values_list(self.rule, '{group_title}', k['group_title'])
                    self.update_values_list(self.rule, '{group_value}', "")
            else:
                self.rule.append(xml_tags.CONTENT_INI)
                self.create_xml_from_ini(main)
                self.update_values_list(self.rule,
                                        "{select_rules}",
                                        ' '.join(self.select_rules))
            xml_tag = "{main_dir}"
            self.update_values_list(self.rule,
                                    xml_tag,
                                    '_'.join(get_full_xml_tag(self.dirname)))
        return self.rule

    def fnc_config_file(self, key, name):
        """Function updates a config file."""
        if name in key and key[name] is not None:
            self.update_values_list(self.rule, "{config_section}",
                                    xml_tags.CONFIG_SECTION)
            self.update_values_list(self.rule, "{config_file}",
                                    key['config_file'])
        else:
            self.update_values_list(self.rule, "{config_section}", "")

    def fnc_check_script(self, key, name):
        """ Function updates a check_script """
        if name in key:
            self.check_script_modification(key, name)
            self.update_values_list(self.select_rules, "{scap_name}",
                                    key[name].split('.')[0])

    def fnc_check_description(self, key, name):
        """ Function updates a check_description """
        if name in key and key[name] is not None:
            escaped_text = self._update_check_description(key[name])
            self.update_values_list(self.rule, "{check_description}", escaped_text)
        else:
            self.update_values_list(self.rule, "{check_description}", "")

    def fnc_solution_text(self, key, name):
        """Function updates a solution text."""
        if name in key:
            self.solution_modification(key)
        else:
            self.update_values_list(self.rule, "{fix}", xml_tags.FIX_TEXT)
            self.update_values_list(self.rule, "{solution_text}", "text")
            self.update_values_list(self.rule, "{platform_id}",
                                    SystemIdentification.get_assessment_version(self.dirname)[1])

    def fnc_update_mode(self, key, name):

        """
        Function update <upgrade_path>/<migrate.conf|update.conf> files
        migrate_xccdf_path
        :param key:
        :param name:
        :return:
        """

        content = "{rule}{main_dir}_{name}".format(rule=xml_tags.TAG_RULE,
                                                   main_dir='_'.join(get_full_xml_tag(self.dirname)),
                                                   name=key.split('.')[0])
        if not name:
            self.update_files('migrate', content)
            self.update_files('upgrade', content)
        for x in name.split(','):
            self.update_files(x.strip(), content)

    def dummy_fnc(self, key, name):
        """Function is only dummy."""
        pass

    def update_text(self, key, name):
        """Function updates a text."""
        try:
            if key[name] is not None:
                # escape values so they can be loaded as XMLs
                escaped_text = html_escape_string(key[name])
                self.update_values_list(self.rule, "{"+name+"}", escaped_text)
        except KeyError:
            raise MissingTagsIniFileError

    def create_xml_from_ini(self, main):
        """
        The function creates group.xml file from INI file.
        All tag are replaced by function update_value_list

        Function also checks whether check script full fills all criteria
        """
        self.select_rules.append(xml_tags.SELECT_TAG)
        update_fnc = {
            'config_file': self.fnc_config_file,
            'check_script': self.fnc_check_script,
            'check_description': self.fnc_check_description,
            'solution': self.fnc_solution_text,
            'applies_to': self.dummy_fnc,
            'binary_req': self.dummy_fnc,
            'content_title': self.update_text,
            'content_description': self.update_text,
        }
        for key in self.keys:
            if 'check_script' not in key:
                raise MissingTagsIniFileError
            if 'solution' not in key:
                raise MissingTagsIniFileError
            self.mh = ModuleHelper(os.path.dirname(main), key['check_script'], key['solution'])
            self.mh.check_recommended_fields(key)
            # Add solution text into value
            if 'solution' in key:
                xml_tags.DIC_VALUES['solution_file'] = key['solution']
            else:
                xml_tags.DIC_VALUES['solution_file'] = 'solution.txt'

            # Add flag where will be shown content if in admin part or in user part
            if 'result_part' in key:
                xml_tags.DIC_VALUES['result_part'] = key['result_part']
            else:
                xml_tags.DIC_VALUES['result_part'] = 'admin'

            self.update_values_list(self.rule, "{rule_tag}", ''.join(xml_tags.RULE_SECTION))
            value_tag, check_export_tag = self.add_value_tag()
            self.update_values_list(self.rule, "{check_export}", ''.join(check_export_tag))
            self.update_values_list(self.rule, "{group_value}", ''.join(value_tag))

            try:
                for k, function in six.iteritems(update_fnc):
                    try:
                        function(key, k)
                    except IOError as e:
                        e_title = "Wrong value for tag '%s' in INI file '%s'\n" % (k, main)
                        e_msg = "'%s': %s" % (key[k], e.strerror)
                        MessageHelper.print_error_msg(title=e_title, msg=e_msg)
                        raise MissingTagsIniFileError
            except MissingTagsIniFileError:
                title = "Following tag '%s' is missing in INI File %s\n" % (k, main)
                MessageHelper.print_error_msg(title=title)
                raise MissingTagsIniFileError

            self.update_values_list(self.rule, '{group_title}', html_escape_string(key['content_title']))
            try:
                if 'mode' not in key:
                    self.fnc_update_mode(key['check_script'], 'migrate, upgrade')
                else:
                    self.fnc_update_mode(key['check_script'], key['mode'])
            except KeyError:
                pass