# Lint as: python2, python3
# Copyright 2016 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 is a server side WebRTC audio test using the Chameleon board."""

import logging
import os
import time

from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.audio import audio_test_data
from autotest_lib.client.cros.chameleon import audio_test_utils
from autotest_lib.client.cros.chameleon import chameleon_audio_helper
from autotest_lib.client.cros.chameleon import chameleon_audio_ids
from autotest_lib.client.cros.multimedia import webrtc_utils
from autotest_lib.server.cros.audio import audio_test
from autotest_lib.server.cros.multimedia import remote_facade_factory


class audio_AudioWebRTCLoopback(audio_test.AudioTest):
    """Server side WebRTC loopback audio test.

    This test talks to a Chameleon board and a Cros device to verify
    WebRTC audio function of the Cros device.
    A sine tone is played to Cros device from Chameleon USB.
    Through AppRTC loopback page, the sine tone is played to Chameleon
    LineIn from Cros device headphone.
    Using USB as audio source because it can provide completely correct
    data to loopback. This enables the test to do quality verification on
    headphone.

                  ----------->->->------------
         USB out |                            | USB in
           -----------                    --------              AppRTC loopback
          | Chameleon |                  |  Cros  |  <--------> webpage
           -----------                    --------
         Line-In |                            |  Headphone
                  -----------<-<-<------------


    The recorded audio is copied to server side and examined for quality.

    """
    version = 1
    RECORD_SECONDS = 10
    DELAY_AFTER_BINDING_SECONDS = 0.5

    def run_once(self, host, check_quality=False, chrome_block_size=None):
        """Running basic headphone audio tests.

        @param host: device under test host
        @param check_quality: flag to check audio quality.
        @param chrome_block_size: A number to be passed to Chrome
                                  --audio-buffer-size argument to specify
                                  block size.

        """
        if not audio_test_utils.has_audio_jack(host):
            raise error.TestNAError(
                    'No audio jack for the DUT.'
                    'Please check label of the host and control file.'
                    'Please check the host label and test dependency.')

        golden_file = audio_test_data.GenerateAudioTestData(
                data_format=dict(file_type='wav',
                                 sample_format='S16_LE',
                                 channel=2,
                                 rate=48000),
                path=os.path.join(self.bindir, 'fix_660_16.wav'),
                duration_secs=60,
                frequencies=[660, 660])

        chameleon_board = host.chameleon

        # Checks if a block size is specified for Chrome.
        extra_browser_args = None
        if chrome_block_size:
            extra_browser_args = ['--audio-buffer-size=%d' % chrome_block_size]

        factory = remote_facade_factory.RemoteFacadeFactory(
                host, results_dir=self.resultsdir,
                extra_browser_args=extra_browser_args)

        chameleon_board.setup_and_reset(self.outputdir)

        widget_factory = chameleon_audio_helper.AudioWidgetFactory(
                factory, host)

        headphone = widget_factory.create_widget(
            chameleon_audio_ids.CrosIds.HEADPHONE)
        linein = widget_factory.create_widget(
            chameleon_audio_ids.ChameleonIds.LINEIN)
        headphone_linein_binder = widget_factory.create_binder(headphone, linein)

        usb_out = widget_factory.create_widget(chameleon_audio_ids.ChameleonIds.USBOUT)
        usb_in = widget_factory.create_widget(chameleon_audio_ids.CrosIds.USBIN)
        usb_binder = widget_factory.create_binder(usb_out, usb_in)

        with chameleon_audio_helper.bind_widgets(headphone_linein_binder):
            with chameleon_audio_helper.bind_widgets(usb_binder):
                time.sleep(self.DELAY_AFTER_BINDING_SECONDS)
                audio_facade = factory.create_audio_facade()

                audio_test_utils.dump_cros_audio_logs(
                        host, audio_facade, self.resultsdir, 'after_binding')

                # Checks whether line-out or headphone is detected.
                hp_jack_node_type = audio_test_utils.check_hp_or_lineout_plugged(
                        audio_facade)

                # Checks headphone and USB nodes are plugged.
                # Let Chrome select the proper I/O nodes.
                # Input is USB, output is headphone.
                audio_test_utils.check_and_set_chrome_active_node_types(
                        audio_facade=audio_facade,
                        output_type=hp_jack_node_type,
                        input_type='USB')

                logging.info('Setting playback data on Chameleon')
                usb_out.set_playback_data(golden_file)

                browser_facade = factory.create_browser_facade()
                apprtc = webrtc_utils.AppRTCController(browser_facade)
                logging.info('Load AppRTC loopback webpage')
                apprtc.new_apprtc_loopback_page()

                logging.info('Start recording from Chameleon.')
                linein.start_recording()

                logging.info('Start playing %s on Cros device',
                        golden_file.path)
                usb_out.start_playback()

                time.sleep(self.RECORD_SECONDS)

                linein.stop_recording()
                logging.info('Stopped recording from Chameleon.')

                audio_test_utils.dump_cros_audio_logs(
                        host, audio_facade, self.resultsdir, 'after_recording')

                usb_out.stop_playback()

                linein.read_recorded_binary()
                logging.info('Read recorded binary from Chameleon.')

        golden_file.delete()

        recorded_file = os.path.join(self.resultsdir, "recorded.raw")
        logging.info('Saving recorded data to %s', recorded_file)
        linein.save_file(recorded_file)

        diagnostic_path = os.path.join(
                self.resultsdir,
                'audio_diagnostics.txt.after_recording')
        logging.info('Examine diagnostic file at %s', diagnostic_path)
        diag_warning_msg = audio_test_utils.examine_audio_diagnostics(
                diagnostic_path)
        if diag_warning_msg:
            logging.warning(diag_warning_msg)

        # Raise error.TestFail if there is issue.
        audio_test_utils.check_recorded_frequency(
                golden_file, linein, check_artifacts=check_quality)
