# Copyright 2021-2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------
import asyncio
import os
import logging
import click
from colors import color
from bumble.company_ids import COMPANY_IDENTIFIERS

from bumble.core import name_or_number
from bumble.hci import (
    map_null_terminated_utf8_string,
    HCI_LE_SUPPORTED_FEATURES_NAMES,
    HCI_SUCCESS,
    HCI_VERSION_NAMES,
    LMP_VERSION_NAMES,
    HCI_Command,
    HCI_Read_BD_ADDR_Command,
    HCI_READ_BD_ADDR_COMMAND,
    HCI_Read_Local_Name_Command,
    HCI_READ_LOCAL_NAME_COMMAND
)
from bumble.host import Host
from bumble.transport import open_transport_or_link


# -----------------------------------------------------------------------------
async def get_classic_info(host):
    if host.supports_command(HCI_READ_BD_ADDR_COMMAND):
        response = await host.send_command(HCI_Read_BD_ADDR_Command())
        if response.return_parameters.status == HCI_SUCCESS:
            print()
            print(color('Classic Address:', 'yellow'), response.return_parameters.bd_addr)

    if host.supports_command(HCI_READ_LOCAL_NAME_COMMAND):
        response = await host.send_command(HCI_Read_Local_Name_Command())
        if response.return_parameters.status == HCI_SUCCESS:
            print()
            print(color('Local Name:', 'yellow'), map_null_terminated_utf8_string(response.return_parameters.local_name))


# -----------------------------------------------------------------------------
async def get_le_info(host):
    print()
    print(color('LE Features:', 'yellow'))
    for feature in host.supported_le_features:
        print('  ', name_or_number(HCI_LE_SUPPORTED_FEATURES_NAMES, feature))


# -----------------------------------------------------------------------------
async def async_main(transport):
    print('<<< connecting to HCI...')
    async with await open_transport_or_link(transport) as (hci_source, hci_sink):
        print('<<< connected')

        host = Host(hci_source, hci_sink)
        await host.reset()

        # Print version
        print(color('Version:', 'yellow'))
        print(color('  Manufacturer:  ', 'green'), name_or_number(COMPANY_IDENTIFIERS, host.local_version.company_identifier))
        print(color('  HCI Version:   ', 'green'), name_or_number(HCI_VERSION_NAMES, host.local_version.hci_version))
        print(color('  HCI Subversion:', 'green'), host.local_version.hci_subversion)
        print(color('  LMP Version:   ', 'green'), name_or_number(LMP_VERSION_NAMES, host.local_version.lmp_version))
        print(color('  LMP Subversion:', 'green'), host.local_version.lmp_subversion)

        # Get the Classic info
        await get_classic_info(host)

        # Get the LE info
        await get_le_info(host)

        # Print the list of commands supported by the controller
        print()
        print(color('Supported Commands:', 'yellow'))
        for command in host.supported_commands:
            print('  ', HCI_Command.command_name(command))


# -----------------------------------------------------------------------------
@click.command()
@click.argument('transport')
def main(transport):
    logging.basicConfig(level = os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
    asyncio.run(async_main(transport))


# -----------------------------------------------------------------------------
if __name__ == '__main__':
    main()
