# 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.

"""An adapter to remotely access the audio facade on DUT."""

import os
import tempfile


class AudioFacadeError(Exception):
    """Errors in audio facade."""
    pass


class AudioFacadeRemoteAdapter(object):
    """AudioFacadeRemoteAdapter is an adapter to remotely control DUT audio.

    The Autotest host object representing the remote DUT, passed to this
    class on initialization, can be accessed from its _client property.

    """
    def __init__(self, host, remote_facade_proxy):
        """Construct an AudioFacadeRemoteAdapter.

        @param host: Host object representing a remote host.
        @param remote_facade_proxy: RemoteFacadeProxy object.

        """
        self._client = host
        self._proxy = remote_facade_proxy


    @property
    def _audio_proxy(self):
        """Gets the proxy to DUT audio facade.

        @return XML RPC proxy to DUT audio facade.

        """
        return self._proxy.audio


    def playback(self, client_path, data_format, blocking=False,
                 node_type=None, block_size=None):
        """Playback an audio file on DUT.

        @param client_path: The path to the file on DUT.
        @param data_format: A dict containing data format including
                            file_type, sample_format, channel, and rate.
                            file_type: file type e.g. 'raw' or 'wav'.
                            sample_format: One of the keys in
                                           audio_data.SAMPLE_FORMAT.
                            channel: number of channels.
                            rate: sampling rate.
        @param blocking: Blocks this call until playback finishes.
        @param node_type: A Cras node type defined in cras_utils.CRAS_NODE_TYPES
                          that we like to pin at. None to have the playback on
                          active selected device.
        @param block_size: The number for frames per callback.

        """
        self._audio_proxy.playback(
                client_path, data_format, blocking, node_type, block_size)


    def stop_playback(self):
        """Stops playback process."""
        self._audio_proxy.stop_playback()


    def set_playback_file(self, path):
        """Copies a file to client.

        @param path: A path to the file.

        @returns: A new path to the file on client.

        """
        _, ext = os.path.splitext(path)
        _, client_file_path = tempfile.mkstemp(
                prefix='playback_', suffix=ext)
        self._client.send_file(path, client_file_path)
        return client_file_path


    def start_recording(self, data_format, node_type=None, block_size=None):
        """Starts recording an audio file on DUT.

        @param data_format: A dict containing:
                            file_type: 'raw'.
                            sample_format: 'S16_LE' for 16-bit signed integer in
                                           little-endian.
                            channel: channel number.
                            rate: sampling rate.
        @param node_type: A Cras node type defined in cras_utils.CRAS_NODE_TYPES
                          that we like to pin at. None to have the recording
                          from active selected device.
        @param block_size: The number for frames per callback.

        @returns: True

        """
        self._audio_proxy.start_recording(data_format, node_type, block_size)
        return True


    def stop_recording(self, node_type=None):
        """Stops recording on DUT.

        @param node_type: A Cras node type defined in cras_utils.CRAS_NODE_TYPES
                          that we like to stop recording from. None to stop the
                          recording from active selected device.

        @returns: the path to the recorded file on DUT.

        @raises: AudioFacadeError if recorded path is None
        """
        path = self._audio_proxy.stop_recording(node_type)
        if not path:
            raise AudioFacadeError(
                    'Recording does not work on DUT. '
                    'Suggest checking messages on DUT')
        return path


    def start_listening(self, data_format):
        """Starts listening horword on DUT.

        @param data_format: A dict containing:
                            file_type: 'raw'.
                            sample_format: 'S16_LE' for 16-bit signed integer in
                                           little-endian.
                            channel: channel number.
                            rate: sampling rate.

        @returns: True

        """
        self._audio_proxy.start_listening(data_format)
        return True


    def stop_listening(self):
        """Stops listening on DUT.

        @returns: the path to the recorded file on DUT.

        @raises: AudioFacadeError if hotwording does not work on DUT.
        """
        path = self._audio_proxy.stop_listening()
        if not path:
            raise AudioFacadeError('Listening does not work on DUT.')
        return path


    def get_recorded_file(self, remote_path, local_path):
        """Gets a recorded file from DUT.

        @param remote_path: The path to the file on DUT.
        @param local_path: The local path for copy destination.

        """
        self._client.get_file(remote_path, local_path)


    def set_selected_output_volume(self, volume):
        """Sets the selected output volume on DUT.

        @param volume: the volume to be set(0-100).

        """
        self._audio_proxy.set_selected_output_volume(volume)


    def set_input_gain(self, gain):
        """Sets the system capture gain.

        @param gain: the capture gain in db*100 (100 = 1dB)

        """
        self._audio_proxy.set_input_gain(gain)


    def set_selected_node_types(self, output_node_types, input_node_types):
        """Set selected node types.

        The node types are defined in cras_utils.CRAS_NODE_TYPES.

        @param output_node_types: A list of output node types.
                                  None to skip setting.
        @param input_node_types: A list of input node types.
                                 None to skip setting.

        """
        self._audio_proxy.set_selected_node_types(
                output_node_types, input_node_types)


    def get_selected_node_types(self):
        """Gets the selected output and input node types on DUT.

        @returns: A tuple (output_node_types, input_node_types) where each
                  field is a list of selected node types defined in
                  cras_utils.CRAS_NODE_TYPES.

        """
        return self._audio_proxy.get_selected_node_types()


    def get_plugged_node_types(self):
        """Gets the plugged output and input node types on DUT.

        @returns: A tuple (output_node_types, input_node_types) where each
                  field is a list of plugged node types defined in
                  cras_utils.CRAS_NODE_TYPES.

        """
        return self._audio_proxy.get_plugged_node_types()


    def dump_diagnostics(self, file_path):
        """Dumps audio diagnostics results to a file.

        @param file_path: The path to dump results.

        @returns: True

        """
        _, remote_path = tempfile.mkstemp(
                prefix='audio_dump_', suffix='.txt')
        self._audio_proxy.dump_diagnostics(remote_path)
        self._client.get_file(remote_path, file_path)
        return True


    def start_counting_signal(self, signal_name):
        """Starts counting DBus signal from Cras.

        @param signal_name: Signal of interest.

        """
        self._audio_proxy.start_counting_signal(signal_name)


    def stop_counting_signal(self):
        """Stops counting DBus signal from Cras.

        @returns: Number of signals counted starting from last
                  start_counting_signal call.

        """
        return self._audio_proxy.stop_counting_signal()


    def wait_for_unexpected_nodes_changed(self, timeout_secs):
        """Waits for unexpected nodes changed signal.

        @param timeout_secs: Timeout in seconds for waiting.

        """
        self._audio_proxy.wait_for_unexpected_nodes_changed(timeout_secs)


    def get_chrome_audio_availablity(self):
        """Gets if the chrome.audio API is ready.

        @returns: chrome.audio is ready or not.
        """
        return self._audio_proxy.get_audio_availability()


    def set_chrome_active_volume(self, volume):
        """Sets the active audio output volume using chrome.audio API.

        @param volume: Volume to set (0~100).

        """
        self._audio_proxy.set_chrome_active_volume(volume)


    def set_chrome_mute(self, mute):
        """Mutes the active audio output using chrome.audio API.

        @param mute: True to mute. False otherwise.

        """
        self._audio_proxy.set_chrome_mute(mute)

    def check_audio_stream_at_selected_device(self):
        """Checks the audio output is at expected node"""
        self._audio_proxy.check_audio_stream_at_selected_device()


    def get_chrome_active_volume_mute(self):
        """Gets the volume state of active audio output using chrome.audio API.

        @param returns: A tuple (volume, mute), where volume is 0~100, and mute
                        is True if node is muted, False otherwise.

        """
        return self._audio_proxy.get_chrome_active_volume_mute()


    def set_chrome_active_node_type(self, output_node_type, input_node_type):
        """Sets active node type through chrome.audio API.

        The node types are defined in cras_utils.CRAS_NODE_TYPES.
        The current active node will be disabled first if the new active node
        is different from the current one.

        @param output_node_type: A node type defined in
                                 cras_utils.CRAS_NODE_TYPES. None to skip.
        @param input_node_type: A node type defined in
                                 cras_utils.CRAS_NODE_TYPES. None to skip

        """
        self._audio_proxy.set_chrome_active_node_type(
                output_node_type, input_node_type)


    def start_arc_recording(self):
        """Starts recording using microphone app in container."""
        self._audio_proxy.start_arc_recording()


    def stop_arc_recording(self):
        """Checks the recording is stopped and gets the recorded path.

        The recording duration of microphone app is fixed, so this method just
        asks Cros device to copy the recorded result from container to a path
        on Cros device.

        @returns: Path to the recorded file on DUT.

        """
        return self._audio_proxy.stop_arc_recording()


    def set_arc_playback_file(self, path):
        """Copies the file from server to Cros host and into container.

        @param path: Path to the file on server.

        @returns: Path to the file in container on Cros host.

        """
        client_file_path = self.set_playback_file(path)
        return self._audio_proxy.set_arc_playback_file(client_file_path)


    def start_arc_playback(self, path):
        """Starts playback through ARC on Cros host.

        @param path: Path to the file in container on Cros host.

        """
        self._audio_proxy.start_arc_playback(path)


    def stop_arc_playback(self):
        """Stops playback through ARC on Cros host."""
        self._audio_proxy.stop_arc_playback()
