class Neighbors(Util):
    """Junos Neighbor Class

    :param dev: connected device
    :type dev: jnpr.junos.Device

    :reises: jnpr.junos.exception
    """

    @property
    def lldp(self):
        if not hasattr(self, '_lldp'):
            self._lldp = LLDPNeighborTable(self.dev)
        return self._lldp.get()

    @property
    def isis(self):
        if not hasattr(self, '_isis'):
            self._isis = IsisAdjacencyTable(self.dev)
        return self._isis.get()

    @property
    def ospf(self):
        if not hasattr(self, '_ospf'):
            self._ospf = OspfNeighborTable(self.dev)
        return self._ospf.get()

    def all(self):
        """Return ALL Neighbors with protocols

        :return: dict of neighbors with IFD as key
        :rtype: dict
        """
        neighbors = defaultdict(lambda: {'protocols': set()})
        for lldp in self.lldp:
            neighbors[lldp.local_int]['hostname'] = lldp.remote_sysname
            neighbors[lldp.local_int]['protocols'].add('lldp')
        for isis in self.isis:
            ifd, unit = isis.interface_name.split('.')
            if 'hostname' not in neighbors[ifd]:
                neighbors[ifd]['hostname'] = isis.system_name
            neighbors[ifd]['protocols'].add('isis')
        for ospf in self.ospf:
            ifd, unit = ospf.interface_name.split('.')
            if 'hostname' not in neighbors[ifd]:
                try:
                    dns_name = socket.gethostbyaddr(ospf.neighbor_id)[0]
                    neighbors[ifd]['hostname'] = dns_name
                except socket.herror:
                    neighbors[ifd]['hostname'] = ospf.neighbor_id
            neighbors[ifd]['protocols'].add('ospf')
        return neighbors

    def display(self):
        """Display ALL Neighbors"""
        print("Neighbors:")
        print("%-16s %-16s %s" % ('Interface', 'Hostname', 'Protocols'))
        for ifd, attributes in self.all().iteritems():
            print("%-16s %-16s %s" % (ifd, attributes['hostname'],
                  ", ".join(attributes['protocols'])))
 def isis(self):
     if not hasattr(self, '_isis'):
         self._isis = IsisAdjacencyTable(self.dev)
     return self._isis.get()