from jnpr.junos.exception import RpcError


def provides_facts():
    """
    Returns a dictionary keyed on the facts provided by this module. The value
    of each key is the doc string describing the fact.
    """
    return {'vc_capable': "A boolean indicating if the device is currently "
                          "configured in a virtual chassis. In spite of the "
                          "name, this fact does NOT indicate whether or not "
                          "the device is CAPABLE of joining a VC.",
            'vc_mode': "A string indicating the current virtual chassis "
                       "mode of the device.",
            'vc_fabric': "A boolean indicating if the device is currently in "
                         "fabric mode.",
            'vc_master': "A string indicating the chassis/node which is "
                         "currently the master of the VC.", }


def get_facts(device):
    """
    Gathers facts from the <get-virtual-chassis-information/> RPC.
    """
    vc_capable = None
    vc_mode = None
    vc_fabric = None
    vc_master = None

    try:
        rsp = device.rpc.get_virtual_chassis_information(normalize=True)
        # MX issue where command returns, but without content. In this case,
        # rsp is set to True.
        if rsp is not True:
            vc_capable = True
            if rsp is not None:
                vc_mode = rsp.findtext('.//virtual-chassis-mode')
                vc_id_info = rsp.find('.//virtual-chassis-id-information')
                if vc_id_info is not None:
                    if vc_id_info.get('style') == 'fabric':
                        vc_fabric = True
                    else:
                        vc_fabric = False
                for member_id in rsp.xpath(
                        ".//member-role[starts-with(.,'Master')]"
                        "/preceding-sibling::member-id"):
                    if vc_master is None:
                        vc_master = member_id.text
                    else:
                        old_vc_master = vc_master
                        vc_master = None
                        raise ValueError("Member %s and member %s both claim "
                                         "to be master of the VC." %
                                         (old_vc_master, member_id.text))
        else:
            vc_capable = False
    except RpcError:
        # Likely a device that doesn't implement the
        # <get-virtual-chassis-information/> RPC.
        # That's OK. Set vc_capable = False.
        vc_capable = False

    return {'vc_capable': vc_capable,
            'vc_mode': vc_mode,
            'vc_fabric': vc_fabric,
            'vc_master': vc_master, }
