# Path: nbxmpp/util.py
# class Observable:
#     def __init__(self, log_: logging.Logger):
#         self._log = log_
#         self._frozen = False
#         self._callbacks: defaultdict[str, list[Callable[..., Any]]] = defaultdict(list)
# 
#     def remove_subscriptions(self):
#         self._callbacks = defaultdict(list)
# 
#     def subscribe(self, signal_name: str, func: Callable[..., Any]):
#         self._callbacks[signal_name].append(func)
# 
#     def notify(self, signal_name: str, *args: Any, **kwargs: dict[str, Any]):
#         if self._frozen:
#             self._frozen = False
#             return
# 
#         self._log.info('Signal: %s', signal_name)
#         callbacks = self._callbacks.get(signal_name, [])
#         for func in callbacks:
#             func(self, signal_name, *args, **kwargs)
# 
# Path: nbxmpp/resolver.py
# class GioResolver(metaclass=Singleton):
#     def __init__(self):
#         self._cache = {}
# 
#     def _cache_request(self, request):
#         self._cache[request] = request
# 
#     def resolve_alternatives(self, domain, callback):
#         request = AlternativeMethods(self._cache, domain, callback)
#         if request.is_cached:
#             request.finalize()
#             return
# 
#         Gio.Resolver.get_default().lookup_records_async(
#             request.hostname,
#             Gio.ResolverRecordType.TXT,
#             None,
#             self._on_alternatives_result,
#             request)
# 
#     def _on_alternatives_result(self, resolver, result, request):
#         try:
#             results = resolver.lookup_records_finish(result)
#         except GLib.Error as error:
#             log.info(error)
#             request.finalize()
#             return
# 
#         try:
#             websocket_uri = self._parse_alternative_methods(results)
#         except Exception:
#             log.exception('Failed to parse alternative '
#                           'connection methods: %s', results)
#             request.finalize()
#             return
# 
#         request.result = websocket_uri
#         self._cache_request(request)
#         request.finalize()
# 
#     @staticmethod
#     def _parse_alternative_methods(variant_results):
#         result_list = [res[0][0] for res in variant_results]
#         for result in result_list:
#             if result.startswith('_xmpp-client-websocket'):
#                 return result.split('=')[1]
#         return None
# 
# Path: nbxmpp/const.py
# class ConnectionType(Enum):
#     DIRECT_TLS = 'DIRECT TLS'
#     START_TLS = 'START TLS'
#     PLAIN = 'PLAIN'
# 
#     @property
#     def is_direct_tls(self):
#         return self == ConnectionType.DIRECT_TLS
# 
#     @property
#     def is_start_tls(self):
#         return self == ConnectionType.START_TLS
# 
#     @property
#     def is_plain(self):
#         return self == ConnectionType.PLAIN
# 
# Path: nbxmpp/const.py
# class ConnectionProtocol(IntEnum):
#     TCP = 0
#     WEBSOCKET = 1


import logging
from collections import namedtuple
from nbxmpp.util import Observable
from nbxmpp.resolver import GioResolver
from nbxmpp.const import ConnectionType
from nbxmpp.const import ConnectionProtocol
        if address is None:
            return

        host_or_uri, protocol, type_ = address
        if protocol == ConnectionProtocol.WEBSOCKET:
            host, uri = None, host_or_uri
        else:
            host, uri = host_or_uri, None

        self._fallback_addresses = []
        self._addresses = [
            ServerAddress(domain=self._domain,
                          service=None,
                          host=host,
                          uri=uri,
                          protocol=protocol,
                          type=type_,
                          proxy=None)]

    def set_proxy(self, proxy):
        self._proxy = proxy

    def _on_alternatives_result(self, uri):
        if uri is None:
            self._on_request_resolved()
            return

        if uri.startswith('wss'):
            type_ = ConnectionType.DIRECT_TLS
        elif uri.startswith('ws'):

# Path: nbxmpp/util.py
# class Observable:
#     def __init__(self, log_: logging.Logger):
#         self._log = log_
#         self._frozen = False
#         self._callbacks: defaultdict[str, list[Callable[..., Any]]] = defaultdict(list)
# 
#     def remove_subscriptions(self):
#         self._callbacks = defaultdict(list)
# 
#     def subscribe(self, signal_name: str, func: Callable[..., Any]):
#         self._callbacks[signal_name].append(func)
# 
#     def notify(self, signal_name: str, *args: Any, **kwargs: dict[str, Any]):
#         if self._frozen:
#             self._frozen = False
#             return
# 
#         self._log.info('Signal: %s', signal_name)
#         callbacks = self._callbacks.get(signal_name, [])
#         for func in callbacks:
#             func(self, signal_name, *args, **kwargs)
# 
# Path: nbxmpp/resolver.py
# class GioResolver(metaclass=Singleton):
#     def __init__(self):
#         self._cache = {}
# 
#     def _cache_request(self, request):
#         self._cache[request] = request
# 
#     def resolve_alternatives(self, domain, callback):
#         request = AlternativeMethods(self._cache, domain, callback)
#         if request.is_cached:
#             request.finalize()
#             return
# 
#         Gio.Resolver.get_default().lookup_records_async(
#             request.hostname,
#             Gio.ResolverRecordType.TXT,
#             None,
#             self._on_alternatives_result,
#             request)
# 
#     def _on_alternatives_result(self, resolver, result, request):
#         try:
#             results = resolver.lookup_records_finish(result)
#         except GLib.Error as error:
#             log.info(error)
#             request.finalize()
#             return
# 
#         try:
#             websocket_uri = self._parse_alternative_methods(results)
#         except Exception:
#             log.exception('Failed to parse alternative '
#                           'connection methods: %s', results)
#             request.finalize()
#             return
# 
#         request.result = websocket_uri
#         self._cache_request(request)
#         request.finalize()
# 
#     @staticmethod
#     def _parse_alternative_methods(variant_results):
#         result_list = [res[0][0] for res in variant_results]
#         for result in result_list:
#             if result.startswith('_xmpp-client-websocket'):
#                 return result.split('=')[1]
#         return None
# 
# Path: nbxmpp/const.py
# class ConnectionType(Enum):
#     DIRECT_TLS = 'DIRECT TLS'
#     START_TLS = 'START TLS'
#     PLAIN = 'PLAIN'
# 
#     @property
#     def is_direct_tls(self):
#         return self == ConnectionType.DIRECT_TLS
# 
#     @property
#     def is_start_tls(self):
#         return self == ConnectionType.START_TLS
# 
#     @property
#     def is_plain(self):
#         return self == ConnectionType.PLAIN
# 
# Path: nbxmpp/const.py
# class ConnectionProtocol(IntEnum):
#     TCP = 0
#     WEBSOCKET = 1


# Path: nbxmpp/addresses.py
import logging
from collections import namedtuple
from nbxmpp.util import Observable
from nbxmpp.resolver import GioResolver
from nbxmpp.const import ConnectionType
from nbxmpp.const import ConnectionProtocol

        if address is None:
            return

        host_or_uri, protocol, type_ = address
        if protocol == ConnectionProtocol.WEBSOCKET:
            host, uri = None, host_or_uri
        else:
            host, uri = host_or_uri, None

        self._fallback_addresses = []
        self._addresses = [
            ServerAddress(domain=self._domain,
                          service=None,
                          host=host,
                          uri=uri,
                          protocol=protocol,
                          type=type_,
                          proxy=None)]

    def set_proxy(self, proxy):
        self._proxy = proxy

    def _on_alternatives_result(self, uri):
        if uri is None:
            self._on_request_resolved()
            return

        if uri.startswith('wss'):
            type_ = ConnectionType.DIRECT_TLS
        elif uri.startswith('ws'):

            type_ = ConnectionType.PLAIN