#!/usr/bin/env python3
#   Copyright (c)  2021  Allthenticate, Inc.

"""
The purpose of this module is for demonstrating a main use of Able
"""

# Native modules
import argparse
import asyncio
import logging
import uuid
import sys
from able import ABleCharacteristic, ABleService

# Able modules
from able.advertisement import ABleAdvertisement
from able.bluezdbus import AdvertisementType
from able.peripheral import ABlePeripheralServer

parser = argparse.ArgumentParser(description="Process some integers.")
parser.add_argument(
    "-i",
    "--interface",
    default="/org/bluez/hci0",
    help="Path to the Bluetooth interface (default: /org/bluez/hci0)",
)

args = parser.parse_args()

logging.basicConfig(
    level=logging.DEBUG, format="[%(levelname)8s] (%(filename)s:%(lineno)s) %(message)s"
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


# user-defined connect callback


def connect_callback(*args):
    print("Connected to a central yippee!")


# user-defined disconnect callback
def disconnect_callback(*args):
    print("Disconnected from a central :(")


async def main():
    # Create an able peripheral
    able_peripheral = ABlePeripheralServer(adapter_path=args.interface)
    await able_peripheral.setup_peripheral_server()

    # Add our advertisement with our UUID
    advertisement = ABleAdvertisement(
        local_name="ABle", advertisement_type=AdvertisementType.PERIPHERAL
    )
    advertisement.add_service_uuid("FFF0")
    advertisement.add_service_data("FFF0", bytes.fromhex("0df0ad8b"))
    # windows doesn't support adding manufactuer data to advertisements
    if sys.platform != "win32":
        advertisement.add_manufacturer_data(1234, "1234")
    await able_peripheral.add_advertisement(advertisement)

    # Add an arbitrary service to the application
    service = ABleService(advertisement.le_advertisement.service_uuids[0])
    able_peripheral.add_service(service)

    service = ABleService("FFF1")
    able_peripheral.add_service(service)

    # Add some chars
    chrc1 = ABleCharacteristic(
        characteristic_uuid=uuid.uuid4(), nickname="Comms characteristic"
    )
    able_peripheral.add_characteristic(service, chrc1, is_comms_char=True)

    # Add user defined callbacks
    able_peripheral.add_connect_callback(connect_callback)
    able_peripheral.add_disconnect_callback(disconnect_callback)

    # Start the service
    await able_peripheral.listen()

    while True:
        new_central = await able_peripheral.accept()
        print(f"New connection from {new_central}")

        # Wait 5 seconds then disconnect
        await asyncio.sleep(15)

        try:
            await new_central.close()
        except:
            logger.exception("Exception on close ")


if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(main())
