class BenchmarkHandler(object):
    """
    Class for handling XCCDF benchmark and retrieving data from it (mainly the
    list of profiles).

    """

    def __init__(self, xccdf_file_path, tailoring_file_path=""):
        """
        Constructor for the BenchmarkHandler class.

        :param xccdf_file_path: path to a file with an XCCDF benchmark
        :type xccdf_file_path: str
        :param tailoring_file_path: path to a tailoring file
        :type tailoring_file_path: str
        """

        if not os.path.exists(xccdf_file_path):
            msg = "Invalid file path: '%s'" % xccdf_file_path
            raise BenchmarkHandlingError(msg)

        session = OSCAP.xccdf_session_new(xccdf_file_path)
        if not session:
            msg = "'%s' is not a valid SCAP content file" % xccdf_file_path
            raise BenchmarkHandlingError(msg)

        if tailoring_file_path:
            OSCAP.xccdf_session_set_user_tailoring_file(session,
                                                        tailoring_file_path)
        if OSCAP.xccdf_session_load(session) != 0:
            raise BenchmarkHandlingError(OSCAP.oscap_err_desc())

        # get the benchmark object
        policy_model = OSCAP.xccdf_session_get_policy_model(session)
        benchmark = OSCAP.xccdf_policy_model_get_benchmark(policy_model)

        default_policy = OSCAP.xccdf_policy_new(policy_model, None)
        default_rules_count = OSCAP.xccdf_policy_get_selected_rules_count(default_policy)

        # stores a list of profiles in the benchmark
        self._profiles = []

        if default_rules_count > 0:
            self._profiles.append(
                ProfileInfo(
                    "default", "Default",
                    "The implicit XCCDF profile. Usually, the default contains no rules."))

        if not benchmark:
            msg = "Not a valid benchmark file: '%s'" % xccdf_file_path
            raise BenchmarkHandlingError(msg)

        # iterate over the profiles in the benchmark and store them
        profile_itr = OSCAP.xccdf_benchmark_get_profiles(benchmark)
        while OSCAP.xccdf_profile_iterator_has_more(profile_itr):
            profile = OSCAP.xccdf_profile_iterator_next(profile_itr)

            id_ = OSCAP.xccdf_profile_get_id(profile)
            title = oscap_text_itr_get_text(OSCAP.xccdf_profile_get_title(profile))
            desc = parse_HTML_from_content(oscap_text_itr_get_text(OSCAP.xccdf_profile_get_description(profile)))
            info = ProfileInfo(id_, title, desc)

            self._profiles.append(info)

        if tailoring_file_path:
            tailoring = OSCAP.xccdf_policy_model_get_tailoring(policy_model)
            profile_itr = OSCAP.xccdf_tailoring_get_profiles(tailoring)
            while OSCAP.xccdf_profile_iterator_has_more(profile_itr):
                profile = OSCAP.xccdf_profile_iterator_next(profile_itr)

                id_ = OSCAP.xccdf_profile_get_id(profile)
                title = oscap_text_itr_get_text(OSCAP.xccdf_profile_get_title(profile))
                desc = parse_HTML_from_content(oscap_text_itr_get_text(OSCAP.xccdf_profile_get_description(profile)))
                info = ProfileInfo(id_, title, desc)

                self._profiles.append(info)

        OSCAP.xccdf_profile_iterator_free(profile_itr)
        OSCAP.xccdf_session_free(session)

    @property
    def profiles(self):
        """Property for the list of profiles defined in the benchmark."""

        return self._profiles

