# Copyright 2014 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.
"""Audio port ids shared in Chameleon audio test framework"""


class ChameleonIds(object):
    """Ids for audio ports on Chameleon

    An Id is composed by host name 'Chameleon' and interface name e.g. 'HDMI'.
    Note that the interface name must match what get_connector_type method
    returns on a ChameleonPort so ChameleonPortFinder can find the port.

    """
    HDMI = 'Chameleon HDMI'
    LINEIN = 'Chameleon LineIn'
    LINEOUT = 'Chameleon LineOut'
    MIC = 'Chameleon Mic'
    USBIN = 'Chameleon USBIn'
    USBOUT = 'Chameleon USBOut'

    SINK_PORTS = [HDMI, LINEIN, MIC, USBIN]
    SOURCE_PORTS = [LINEOUT, USBOUT]


class CrosIds(object):
    """Ids for audio ports on Cros device.

    Note that an bidirectional interface like 3.5mm jack is separated to
    two interfaces, that is, 'Headphone' and 'External Mic'.

    """
    HDMI = 'Cros HDMI'
    HEADPHONE = 'Cros Headphone'
    EXTERNAL_MIC = 'Cros External Mic'
    SPEAKER = 'Cros Speaker'
    INTERNAL_MIC = 'Cros Internal Mic'
    BLUETOOTH_HEADPHONE = 'Cros Bluetooth Headphone'
    BLUETOOTH_MIC = 'Cros Bluetooth Mic'
    USBIN = 'Cros USBIn'
    USBOUT = 'Cros USBOut'
    HOTWORDING = 'Cros Hotwording'

    SINK_PORTS = [EXTERNAL_MIC, INTERNAL_MIC, BLUETOOTH_MIC, USBIN, HOTWORDING]
    SOURCE_PORTS = [HDMI, HEADPHONE, SPEAKER, BLUETOOTH_HEADPHONE, USBOUT]


class PeripheralIds(object):
    """Ids for peripherals.

    These peripherals will be accessible by Cros device/Chameleon through
    audio board.

    """
    SPEAKER = 'Peripheral Speaker'
    MIC = 'Peripheral Mic'

    # Peripheral devices should have two roles but we only care one.
    # For example, to test internal microphone on Cros device:
    #
    #                                         (air)
    #                    Peripheral Speaker -------> Internal Microphone
    #                         ------                  ------
    # Chameleon LineOut ----> |    |                  |    |
    #                         ------                  ------
    #                        Audio board             Cros device
    #
    # In the above example, peripheral speaker is a sink as it takes signal
    # from audio board. It should be a source as peripheral speaker transfer
    # signal to internal microphone of Cros device,
    # However, we do not abstract air as a link because it does not contain
    # properties like level, channel_map, occupied to manipulate.
    # So, we set peripheral speaker to be a sink to reflect the part related
    # to audio bus.
    #
    # For example, to test internal speaker on Cros device:
    #
    #                                         (air)
    #                    Peripheral Micropone <----- Internal Speaker
    #                         ------                  ------
    # Chameleon LineIn <----  |    |                  |    |
    #                         ------                  ------
    #                        Audio board             Cros device
    #
    # In the above example, peripheral microphone is a source as it feeds signal
    # to audio board. It should be a sink as peripheral microphone receives
    # signal from internal speaker of Cros device.
    # However, we do not abstract air as a link because it does not contain
    # properties like level, channel_map, occupied to manipulate.
    # So, we set peripheral microphone to be a source to reflect the part related
    # to audio bus.

    BLUETOOTH_DATA_RX = ('Peripheral Bluetooth Signal Output and Data Receiver')
    BLUETOOTH_DATA_TX = ('Peripheral Bluetooth Signal Input and Data '
                         'Transmitter')

    # Bluetooth module has both source and sink roles.
    # When Cros device plays audio to bluetooth module data receiver through
    # bluetooth connection, bluetooth module is a sink of audio signal.
    # When we route audio signal from bluetooth signal output to Chameleon
    # Line-In, bluetooth module is a signal source in terms of audio bus.
    #
    #                     Bluetooth module
    #
    #                    signal     data      (bluetooth)
    #                    output    receiver <------------ Bluetooth Headphone
    #                         ------                        ------
    # Chameleon LineIn <----  |    |                        |    |
    #                         ------                        ------
    #                        Audio board                   Cros device
    #
    #
    # When Cros device records audio from bluetooth module data transmitter
    # through bluetooth connection, bluetooth module is a source of audio
    # signal. When we route audio signal from Chameleon Line-Out to bluetooth
    # signal input, bluetooth module is a signal sink in terms of audio bus.
    #
    #                     Bluetooth module
    #
    #                    signal     data      (bluetooth)
    #                    input    transmitter -----------> Bluetooth Microphone
    #                         ------                        ------
    # Chameleon LineOut ----> |    |                        |    |
    #                         ------                        ------
    #                        Audio board                   Cros device
    #
    # From above diagram it is clear that "signal output" is connected to
    # "data receiver", while "signal input" is connected to "data transmitter".
    # To simplify the number of nodes, we group "signal output" and
    # "data receiver" into one Id, and group "signal input" and
    # "data transmitter" into one Id. Also, we let these two Ids be both source
    # and sink.
    SOURCE_PORTS = [MIC, BLUETOOTH_DATA_RX, BLUETOOTH_DATA_TX]
    SINK_PORTS = [SPEAKER, BLUETOOTH_DATA_RX, BLUETOOTH_DATA_TX]


SINK_PORTS = []
for cls in [ChameleonIds, CrosIds, PeripheralIds]:
    SINK_PORTS += cls.SINK_PORTS

SOURCE_PORTS = []
for cls in [ChameleonIds, CrosIds, PeripheralIds]:
    SOURCE_PORTS += cls.SOURCE_PORTS


def get_host(port_id):
    """Parses given port_id to get host name.

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

    @returns: Host name. A string in ['Chameleon', 'Cros', 'Peripheral'].

    @raises: ValueError if port_id is invalid.

    """
    host = port_id.split()[0]
    if host not in ['Chameleon', 'Cros', 'Peripheral']:
        raise ValueError('Not a valid port id: %r' % port_id)
    return host


def get_interface(port_id):
    """Parses given port_id to get interface name.

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

    @returns: Interface name. A string, e.g. 'HDMI', 'LineIn'.

    @raises: ValueError if port_id is invalid.

    """
    try:
        return port_id.split(' ', 1)[1]
    except IndexError:
        raise ValueError('Not a valid port id: %r' % port_id)


def get_role(port_id):
    """Gets the role of given port_id.

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

    @returns: 'source' or 'sink'.

    @raises: ValueError if port_id is invalid.

    """
    if port_id in SOURCE_PORTS:
        return 'source'
    if port_id in SINK_PORTS:
        return 'sink'
    if port_id in SOURCE_PORTS and port_id in SINK_PORTS:
        return 'sink | source'
    raise ValueError('Not a valid port id: %r' % port_id)
