#!/usr/bin/env python3

""" Example of browsing for a service.

The default is HTTP and HAP; use --find to search for all available services in the network
"""

import argparse
import asyncio
import logging
from typing import cast

from zeroconf import IPVersion, ServiceStateChange
from zeroconf.aio import AsyncServiceBrowser, AsyncZeroconf


def async_on_service_state_change(
    zeroconf: AsyncZeroconf, service_type: str, name: str, state_change: ServiceStateChange
) -> None:
    print("Service %s of type %s state changed: %s" % (name, service_type, state_change))
    if state_change is not ServiceStateChange.Added:
        return
    asyncio.ensure_future(async_display_service_info(zeroconf, service_type, name))


async def async_display_service_info(zeroconf: AsyncZeroconf, service_type: str, name: str) -> None:
    info = await zeroconf.async_get_service_info(service_type, name)
    print("Info from zeroconf.get_service_info: %r" % (info))
    if info:
        addresses = ["%s:%d" % (addr, cast(int, info.port)) for addr in info.parsed_addresses()]
        print("  Name: %s" % name)
        print("  Addresses: %s" % ", ".join(addresses))
        print("  Weight: %d, priority: %d" % (info.weight, info.priority))
        print("  Server: %s" % (info.server,))
        if info.properties:
            print("  Properties are:")
            for key, value in info.properties.items():
                print("    %s: %s" % (key, value))
        else:
            print("  No properties")
    else:
        print("  No info")
    print('\n')


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)

    parser = argparse.ArgumentParser()
    parser.add_argument('--debug', action='store_true')
    version_group = parser.add_mutually_exclusive_group()
    version_group.add_argument('--v6', action='store_true')
    version_group.add_argument('--v6-only', action='store_true')
    args = parser.parse_args()

    if args.debug:
        logging.getLogger('zeroconf').setLevel(logging.DEBUG)
    if args.v6:
        ip_version = IPVersion.All
    elif args.v6_only:
        ip_version = IPVersion.V6Only
    else:
        ip_version = IPVersion.V4Only

    aiozc = AsyncZeroconf(ip_version=ip_version)

    services = ["_http._tcp.local.", "_hap._tcp.local."]
    print("\nBrowsing %s service(s), press Ctrl-C to exit...\n" % services)
    aiobrowser = AsyncServiceBrowser(aiozc, services, handlers=[async_on_service_state_change])

    loop = asyncio.get_event_loop()
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass
    finally:
        loop.run_until_complete(aiobrowser.async_cancel())
        loop.run_until_complete(aiozc.async_close())

@@ -218,16 +218,31 @@
 g import
+ Any, Optional,
  cast%0A%0Af
@@ -350,16 +350,43 @@
 Zeroconf
+, AsyncZeroconfServiceTypes
 %0A%0A%0Adef a
@@ -1596,16 +1596,1001 @@
 '%5Cn')%0A%0A%0A
+class AsyncRunner:%0A    def __init__(self, args: Any) -%3E None:%0A        self.args = args%0A        self.aiobrowser: Optional%5BAsyncServiceBrowser%5D = None%0A        self.aiozc: Optional%5BAsyncZeroconf%5D = None%0A%0A    async def async_run(self) -%3E None:%0A        self.aiozc = AsyncZeroconf(ip_version=ip_version)%0A%0A        services = %5B%22_http._tcp.local.%22, %22_hap._tcp.local.%22%5D%0A        if self.args.find:%0A            services = list(%0A                await AsyncZeroconfServiceTypes.async_find(aiozc=self.aiozc, ip_version=ip_version)%0A            )%0A%0A        print(%22%5CnBrowsing %25s service(s), press Ctrl-C to exit...%5Cn%22 %25 services)%0A        self.aiobrowser = AsyncServiceBrowser(self.aiozc, services, handlers=%5Basync_on_service_state_change%5D)%0A        while True:%0A            await asyncio.sleep(1)%0A%0A    async def async_close(self) -%3E None:%0A        assert self.aiozc is not None%0A        assert self.aiobrowser is not None%0A        await self.aiobrowser.async_cancel()%0A        await self.aiozc.async_close()%0A%0A%0A
 if __nam
@@ -2741,32 +2741,125 @@
 n='store_true')%0A
+    parser.add_argument('--find', action='store_true', help='Browse all available services')%0A
     version_grou
@@ -3307,508 +3307,200 @@
     
-aiozc = A
+loop = a
 sync
-Zeroconf(ip_version=ip_version)%0A%0A    services = %5B%22_http._tcp.local.%22, %22_hap._tcp.local.%22%5D%0A    print(%22%5CnBrowsing %25s service(s), press Ctrl-C to exit...%5Cn%22 %25 services)%0A    aiobrowser = AsyncServiceBrowser(aiozc, services, handlers=%5Basync_on_service_state_change%5D)%0A%0A    loop = asyncio.get_event_loop()%0A    try:%0A        loop.run_forever()%0A    except KeyboardInterrupt:%0A        pass%0A    finally:%0A        loop.run_until_complete(aiobrowser.async_cancel())%0A        loop.run_until_complete(aiozc
+io.get_event_loop()%0A    runner = AsyncRunner(args)%0A    try:%0A        loop.run_until_complete(runner.async_run())%0A    except KeyboardInterrupt:%0A        loop.run_until_complete(runner
 .asy

Update async_browser.py example to use AsyncZeroconfServiceTypes (#665)