# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This module provides the utilities for bluetooth audio using chameleon."""

import logging
import time

from autotest_lib.client.bin import utils


_PIN = '0000'
_SEARCH_TIMEOUT = 30.0
_PAIRING_TIMEOUT = 5.0
_SLEEP_AFTER_DISCONNECT = 20.0
# When device is busy, a trial may take more than 15 seconds.
# Set the timeout to 90 seconds so device can take more trials to reconnect.
_CONNECT_TIMEOUT = 90.0

class ChameleonBluetoothAudioError(Exception):
    """Error in this module."""
    pass


def connect_bluetooth_module_full_flow(bt_adapter, target_mac_address,
                             timeout=_SEARCH_TIMEOUT):
    """Controls Cros device to connect to bluetooth module on audio board.

    @param bt_adapter: A BluetoothDevice object to control bluetooth adapter
                       on Cros device.
    @param target_mac_address: The MAC address of bluetooth module to be
                               connected.
    @param timeout: Timeout in seconds to search for bluetooth module.

    @raises: ChameleonBluetoothAudioError if Cros device fails to connect to
             bluetooth module on audio board.

    """
    # Resets bluetooth adapter on Cros device.
    if not bt_adapter.reset_on():
        raise ChameleonBluetoothAudioError(
                'Failed to reset bluetooth adapter on Cros host.'
                ' You should check if controller is available on Cros host'
                ' using bluetoothctl.')

    # Starts discovery mode of bluetooth adapter.
    if not bt_adapter.start_discovery():
        raise ChameleonBluetoothAudioError(
                'Failed to start discovery on bluetooth adapter on Cros host')

    def _find_device():
        """Controls bluetooth adapter to search for bluetooth module.

        @returns: True if there is a bluetooth device with MAC address
                  matches target_mac_address. False otherwise.

        """
        return bt_adapter.has_device(target_mac_address)

    # Searches for bluetooth module with given MAC address.
    found_device = utils.wait_for_value(_find_device, True, timeout_sec=timeout)

    if not found_device:
        raise ChameleonBluetoothAudioError(
                'Can not find bluetooth module with MAC address %s' %
                target_mac_address)

    pair_legacy_bluetooth_module(bt_adapter, target_mac_address)

    # Disconnects from bluetooth module to clean up the state.
    if not bt_adapter.disconnect_device(target_mac_address):
        raise ChameleonBluetoothAudioError(
                'Failed to let Cros device disconnect from bluetooth module %s' %
                target_mac_address)
    time.sleep(_SLEEP_AFTER_DISCONNECT)

    # Connects to bluetooth module.
    connect_bluetooth_module(bt_adapter, target_mac_address)

    logging.info('Bluetooth module at %s is connected', target_mac_address)


def connect_bluetooth_module(bt_adapter, target_mac_address,
                             timeout=_CONNECT_TIMEOUT):
    """Controls Cros device to connect to bluetooth module on audio board.

    @param bt_adapter: A BluetoothDevice object to control bluetooth adapter
                       on Cros device.
    @param target_mac_address: The MAC address of bluetooth module to be
                               connected.
    @param timeout: Timeout in seconds to connect bluetooth module.

    @raises: ChameleonBluetoothAudioError if Cros device fails to connect to
             bluetooth module on audio board.

    """
    def _connect_device():
        logging.info('Try to connect to device')
        success = bt_adapter.connect_device(target_mac_address)
        if not success:
            logging.debug('Can not connect device, retry in 1 second.')
            time.sleep(1)
            return False
        logging.debug('Connection established.')
        return True

    # Connects bluetooth module with given MAC address.
    connected = utils.wait_for_value(_connect_device, True, timeout_sec=timeout)
    if not connected:
        raise ChameleonBluetoothAudioError(
                'Failed to let Cros device connect to bluetooth module %s' %
                target_mac_address)


def pair_legacy_bluetooth_module(bt_adapter, target_mac_address, pin=_PIN,
                                 pairing_timeout=_PAIRING_TIMEOUT, retries=3):
    """Pairs Cros device bluetooth adapter with legacy bluetooth module.

    @param bt_adapter: A BluetoothDevice object to control bluetooth adapter
                       on Cros device.
    @param target_mac_address: The MAC address of bluetooth module to be
                               paired.
    @param pin: The pin for legacy pairing.
    @param timeout: Timeout in seconds to pair bluetooth module in a trial.
    @param retries: Number of retries if pairing fails.

    @raises: ChameleonBluetoothAudioError if Cros device fails to pair
             bluetooth module on audio board after all the retries.

    """
    # Pairs the bluetooth adapter with bluetooth module.
    for trial in xrange(retries):
        if bt_adapter.pair_legacy_device(
            target_mac_address, pin, False, pairing_timeout):
                logging.debug('Pairing to %s succeeded', target_mac_address)
                return
        elif trial == retries - 1:
            raise ChameleonBluetoothAudioError(
                    'Failed to pair Cros device and bluetooth module %s' %
                    target_mac_address)

        logging.debug('Retry for pairing...')
