# 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 audio board interface."""

import logging

from autotest_lib.client.cros.chameleon import chameleon_audio_ids as ids


class AudioBoard(object):
    """AudioBoard is an abstraction of an audio board on a Chameleon board.

    It provides methods to control audio board.

    A ChameleonConnection object is passed to the construction.

    """

    def __init__(self, chameleon_connection):
        """Constructs an AudioBoard.

        @param chameleon_connection: A ChameleonConnection object.

        @returns: An AudioBoard object.

        """
        self._audio_buses = {
                1: AudioBus(1, chameleon_connection),
                2: AudioBus(2, chameleon_connection)
        }
        self._chameleon_connection = chameleon_connection
        self._jack_plugger = None
        self._bluetooth_controller = BluetoothController(chameleon_connection)

    def get_audio_bus(self, bus_index):
        """Gets an audio bus on this audio board.

        @param bus_index: The bus index 1 or 2.

        @returns: An AudioBus object.

        """
        return self._audio_buses[bus_index]

    def get_jack_plugger(self):
        """Gets an AudioJackPlugger on this audio board.

        @returns: An AudioJackPlugger object if there is an audio jack plugger.
                  None if there is no audio jack plugger.
        @raises:
            AudioJackPluggerException if there is no jack plugger on this audio
            board.

        """
        if self._jack_plugger is None:
            try:
                self._jack_plugger = AudioJackPlugger(
                        self._chameleon_connection)
            except AudioJackPluggerException as e:
                logging.error(
                        'There is no jack plugger on this audio board. Please '
                        'check the jack plugger if all labels are correctly '
                        'configured.')
                self._jack_plugger = None
        return self._jack_plugger

    def get_bluetooth_controller(self):
        """Gets an BluetoothController on this audio board.

        @returns: An BluetoothController object.

        """
        return self._bluetooth_controller


class AudioBus(object):
    """AudioBus is an abstraction of an audio bus on an audio board.

    It provides methods to control audio bus.

    A ChameleonConnection object is passed to the construction.

    @properties:
        bus_index: The bus index 1 or 2.

    """
    # Maps port id defined in chameleon_audio_ids to endpoint name used in
    # chameleond audio bus API.
    _PORT_ID_AUDIO_BUS_ENDPOINT_MAP = {
            ids.ChameleonIds.LINEIN: 'Chameleon FPGA line-in',
            ids.ChameleonIds.LINEOUT: 'Chameleon FPGA line-out',
            ids.CrosIds.HEADPHONE: 'Cros device headphone',
            ids.CrosIds.EXTERNAL_MIC: 'Cros device external microphone',
            ids.PeripheralIds.SPEAKER: 'Peripheral speaker',
            ids.PeripheralIds.MIC: 'Peripheral microphone',
            ids.PeripheralIds.BLUETOOTH_DATA_RX: 'Bluetooth module output',
            ids.PeripheralIds.BLUETOOTH_DATA_TX: 'Bluetooth module input'
    }

    class AudioBusSnapshot(object):
        """Abstracts the snapshot of AudioBus for user to restore it later."""

        def __init__(self, endpoints):
            """Initializes an AudioBusSnapshot.

            @param endpoints: A set of endpoints to keep a copy.

            """
            self._endpoints = endpoints.copy()

    def __init__(self, bus_index, chameleon_connection):
        """Constructs an AudioBus.

        @param bus_index: The bus index 1 or 2.
        @param chameleon_connection: A ChameleonConnection object.

        """
        self.bus_index = bus_index
        self._chameleond_proxy = chameleon_connection
        self._connected_endpoints = set()

    def _get_endpoint_name(self, port_id):
        """Gets the endpoint name used in audio bus API.

        @param port_id: A string, that is, id in ChameleonIds, CrosIds, or
                        PeripheralIds defined in chameleon_audio_ids.

        @returns: The endpoint name for the port used in audio bus API.

        """
        return self._PORT_ID_AUDIO_BUS_ENDPOINT_MAP[port_id]

    def _connect_endpoint(self, endpoint):
        """Connects an endpoint to audio bus.

        @param endpoint: An endpoint name in _PORT_ID_AUDIO_BUS_ENDPOINT_MAP.

        """
        logging.debug('Audio bus %s is connecting endpoint %s', self.bus_index,
                      endpoint)
        self._chameleond_proxy.AudioBoardConnect(self.bus_index, endpoint)
        self._connected_endpoints.add(endpoint)

    def _disconnect_endpoint(self, endpoint):
        """Disconnects an endpoint from audio bus.

        @param endpoint: An endpoint name in _PORT_ID_AUDIO_BUS_ENDPOINT_MAP.

        """
        logging.debug('Audio bus %s is disconnecting endpoint %s',
                      self.bus_index, endpoint)
        self._chameleond_proxy.AudioBoardDisconnect(self.bus_index, endpoint)
        self._connected_endpoints.remove(endpoint)

    def connect(self, port_id):
        """Connects an audio port to this audio bus.

        @param port_id: A string, that is, id in ChameleonIds, CrosIds, or
                        PeripheralIds defined in chameleon_audio_ids.

        """
        endpoint = self._get_endpoint_name(port_id)
        self._connect_endpoint(endpoint)

    def disconnect(self, port_id):
        """Disconnects an audio port from this audio bus.

        @param port_id: A string, that is, id in ChameleonIds, CrosIds, or
                        PeripheralIds defined in chameleon_audio_ids.

        """
        endpoint = self._get_endpoint_name(port_id)
        self._disconnect_endpoint(endpoint)

    def clear(self):
        """Disconnects all audio port from this audio bus."""
        self._disconnect_all_endpoints()

    def _disconnect_all_endpoints(self):
        """Disconnects all endpoints from this audio bus."""
        for endpoint in self._connected_endpoints.copy():
            self._disconnect_endpoint(endpoint)

    def get_snapshot(self):
        """Gets the snapshot of AudioBus so user can restore it later.

        @returns: An AudioBus.AudioBusSnapshot object.

        """
        return self.AudioBusSnapshot(self._connected_endpoints)

    def restore_snapshot(self, snapshot):
        """Restore the snapshot.

        @param: An AudioBus.AudioBusSnapshot object got from get_snapshot.

        """
        self._disconnect_all_endpoints()
        logging.debug('Restoring snapshot with %s', snapshot._endpoints)
        for endpoint in snapshot._endpoints:
            self._connect_endpoint(endpoint)


class AudioJackPluggerException(Exception):
    """Errors in AudioJackPlugger."""
    pass


class AudioJackPlugger(object):
    """AudioJackPlugger is an abstraction of plugger controlled by audio board.

    There is a motor in the audio box which can plug/unplug 3.5mm 4-ring
    audio cable to/from audio jack of Cros deivce.
    This motor is controlled by audio board.

    A ChameleonConnection object is passed to the construction.

    """

    def __init__(self, chameleon_connection):
        """Constructs an AudioJackPlugger.

        @param chameleon_connection: A ChameleonConnection object.

        @raises:
            AudioJackPluggerException if there is no jack plugger on
            this audio board.

        """
        self._chameleond_proxy = chameleon_connection
        if not self._chameleond_proxy.AudioBoardHasJackPlugger():
            raise AudioJackPluggerException(
                    'There is no jack plugger on audio board. '
                    'Perhaps the audio board is not connected to audio box.')

    def plug(self):
        """Plugs the audio cable into audio jack of Cros device."""
        self._chameleond_proxy.AudioBoardAudioJackPlug()
        logging.info('Plugged 3.5mm audio cable to Cros device.')

    def unplug(self):
        """Unplugs the audio cable from audio jack of Cros device."""
        self._chameleond_proxy.AudioBoardAudioJackUnplug()
        logging.info('Unplugged 3.5mm audio cable from Cros device.')


class BluetoothController(object):
    """An abstraction of bluetooth module on audio board.

    There is a bluetooth module on the audio board. It can be controlled through
    API provided by chameleon proxy.

    """

    def __init__(self, chameleon_connection):
        """Constructs an BluetoothController.

        @param chameleon_connection: A ChameleonConnection object.

        """
        self._chameleond_proxy = chameleon_connection

    def reset(self):
        """Resets the bluetooth module."""
        self._chameleond_proxy.AudioBoardResetBluetooth()
        logging.info('Resets bluetooth module on audio board.')

    def disable(self):
        """Disables the bluetooth module."""
        self._chameleond_proxy.AudioBoardDisableBluetooth()
        logging.info('Disables bluetooth module on audio board.')

    def is_enabled(self):
        """Checks if the bluetooth module is enabled.

        @returns: True if bluetooth module is enabled. False otherwise.

        """
        return self._chameleond_proxy.AudioBoardIsBluetoothEnabled()
