<commit_before>"""
krb5 Configuration file - File
==============================
krb5 Configuration are ``/etc/krb5.conf`` and ``/etc/krb5.conf.d/*``,
and the content format is similar to ``INI config``, but they include
values that span multiple lines. Multi-line values start with a '{'
and end with a '}', and we join them together by setting the `is_squ`
variable to True while in a multi-line value.

Example:
    >>> krb5_content = '''
    [realms]
     dns_lookup_realm = false
     ticket_lifetime = 24h
     default_ccache_name = KEYRING:persistent:%{uid}
     EXAMPLE.COM = {
      kdc = kerberos.example.com
      admin_server = kerberos.example.com
     }
     pam = {
      debug = false
      krb4_convert = false
      ticket_lifetime = 36000
     }
     [libdefaults]
      dns_lookup_realm = false
      ticket_lifetime = 24h
      EXAMPLE.COM = {
       kdc = kerberos2.example.com
       admin_server = kerberos2.example.com
     }
    # renew_lifetime = 7d
    # forwardable = true
    # rdns = false
    '''.strip()

    >>> from insights.tests import context_wrap
    >>> shared = {Krb5Configuration: Krb5Configuration(context_wrap(krb5_content))}
    >>> krb5_info = shared[Krb5Configuration]
    >>> krb5_info["libdefaults"]["dnsdsd"]
    "false"
    >>> krb5_info["realms"]["EXAMPLE.COM"]["kdc"]
    "kerberos.example.com"
    >>> krb5_info.sections()
    ["libdefaults","realms"]
    >>> krb5_info.has_section("realms")
    True
    >>> krb5_info.has_option("realms", "nosuchoption")
    False
    >>> krb5_info.options("libdefaults")
    ["dns_lookup_realm","ticket_lifetime","EXAMPLE.COM"]
"""


from .. import parser, Parser, get_active_lines, LegacyItemAccess


PREFIX_FOR_LIST = ("includedir", "include", "module")


def _handle_key_value(t_dict, key, value):
    """
    Function to handle key has multi value, and return the values as list.
    """
    if key in t_dict:
        val = t_dict[key]
        if isinstance(val, str):
            val = [val]
        val.append(value)
        return val
    return value


@parser('krb5')
@parser('krb5.conf.d')
class Krb5Configuration(Parser, LegacyItemAccess):
    """
    Class for krb5.conf and krb5.conf.d configuration.

    The Kerberos .ini format is like an ordinary .ini file except that values
    can include a multiple line key-value pair 'relation' that starts with a
    '{' and end with a '}' on a trailing line.  So we track whether we're in
    curly braces by setting `is_squ` when we enter a relation, and clearing
    it when we leave.  Please fill in the remainder of the logic here.<commit_msg>Add docsting for attributes of Krb5Configuration (#454)<commit_after>"""
krb5 Configuration file - File
==============================
krb5 Configuration are ``/etc/krb5.conf`` and ``/etc/krb5.conf.d/*``,
and the content format is similar to ``INI config``, but they include
values that span multiple lines. Multi-line values start with a '{'
and end with a '}', and we join them together by setting the `is_squ`
variable to True while in a multi-line value.

Example:
    >>> krb5_content = '''
    [realms]
     dns_lookup_realm = false
     ticket_lifetime = 24h
     default_ccache_name = KEYRING:persistent:%{uid}
     EXAMPLE.COM = {
      kdc = kerberos.example.com
      admin_server = kerberos.example.com
     }
     pam = {
      debug = false
      krb4_convert = false
      ticket_lifetime = 36000
     }
     [libdefaults]
      dns_lookup_realm = false
      ticket_lifetime = 24h
      EXAMPLE.COM = {
       kdc = kerberos2.example.com
       admin_server = kerberos2.example.com
     }
    # renew_lifetime = 7d
    # forwardable = true
    # rdns = false
    '''.strip()

    >>> from insights.tests import context_wrap
    >>> shared = {Krb5Configuration: Krb5Configuration(context_wrap(krb5_content))}
    >>> krb5_info = shared[Krb5Configuration]
    >>> krb5_info["libdefaults"]["dnsdsd"]
    "false"
    >>> krb5_info["realms"]["EXAMPLE.COM"]["kdc"]
    "kerberos.example.com"
    >>> krb5_info.sections()
    ["libdefaults","realms"]
    >>> krb5_info.has_section("realms")
    True
    >>> krb5_info.has_option("realms", "nosuchoption")
    False
    >>> krb5_info.options("libdefaults")
    ["dns_lookup_realm","ticket_lifetime","EXAMPLE.COM"]
"""


from .. import parser, Parser, get_active_lines, LegacyItemAccess


PREFIX_FOR_LIST = ("includedir", "include", "module")


def _handle_key_value(t_dict, key, value):
    """
    Function to handle key has multi value, and return the values as list.
    """
    if key in t_dict:
        val = t_dict[key]
        if isinstance(val, str):
            val = [val]
        val.append(value)
        return val
    return value


@parser('krb5')
@parser('krb5.conf.d')
class Krb5Configuration(Parser, LegacyItemAccess):
    """
    Class for krb5.conf and krb5.conf.d configuration.

    The Kerberos .ini format is like an ordinary .ini file except that values
    can include a multiple line key-value pair 'relation' that starts with a
    '{' and end with a '}' on a trailing line.  So we track whether we're in
    curly braces by setting `is_squ` when we enter a relation, and clearing
    it when we leave.  Please fill in the remainder of the logic here.

    Attributes:
        includedir (list): The directory list that `krb5.conf` includes via
            `includedir` directive
        include (list): The configuration file list that `krb5.conf` includes
            via `include` directive
        module (list): The module list that `krb5.conf` specifed via `module`
            directive
{'fraction_non_alphanumeric': 0.1216361679224973, 'fraction_numerical': 0.013455328310010764, 'mean_word_length': 3.063411078717201, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5182896', 'n_tokens_mistral': 1816, 'n_tokens_neox': 1764, 'n_words': 504}