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

import logging
import os
import time

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.chameleon import audio_test_utils
from autotest_lib.client.cros.chameleon import audio_widget_link
from autotest_lib.client.cros.chameleon import chameleon_audio_helper
from autotest_lib.client.cros.chameleon import chameleon_audio_ids
from autotest_lib.server.cros.audio import audio_test


class audio_AudioAfterReboot(audio_test.AudioTest):
    """Server side audio test.

    This test talks to a Chameleon board and a Cros device to verify
    audio function of the Cros device after reboot.

    """
    version = 1
    DELAY_BEFORE_RECORD_SECONDS = 0.5
    DELAY_AFTER_BINDING = 0.5
    RECORD_SECONDS = 5
    PRC_RECONNECT_TIMEOUT = 60

    def play_and_record(self, source_widget, recorder_widget=None):
        """Plays and records (if needed) audio.

        @param source_widget: widget to do the playback
        @param recorder_widget: widget to do the recording
            None to skip recording.

        """
        self.check_correct_audio_node_selected()

        # Play, wait for some time, and then start recording if needed.
        source_widget.set_playback_data(self.golden_file)
        logging.debug('Start playing %s', self.golden_file.path)
        source_widget.start_playback()

        if recorder_widget != None:
            time.sleep(self.DELAY_BEFORE_RECORD_SECONDS)
            logging.debug('Start recording.')
            recorder_widget.start_recording()

            time.sleep(self.RECORD_SECONDS)

            recorder_widget.stop_recording()
            logging.debug('Stopped recording.')

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

            recorder_widget.read_recorded_binary()
        else:
            time.sleep(self.RECORD_SECONDS)

    def save_and_check_data(self, recorder_widget):
        """Saves and checks the data from the recorder.

        @param recorder_widget: recorder widget to save data from

        @raise error.TestFail: if comparison fails

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

        # Removes the beginning of recorded data. This is to avoid artifact
        # caused by codec initialization in the beginning of recording.
        recorder_widget.remove_head(2.0)

        # Removes noise by a lowpass filter.
        recorder_widget.lowpass_filter(self.low_pass_freq)
        recorded_file = os.path.join(self.resultsdir, "recorded_filtered.raw")
        logging.debug('Saving filtered data to %s', recorded_file)
        recorder_widget.save_file(recorded_file)

        # Compares data by frequency.
        audio_test_utils.check_recorded_frequency(
                self.golden_file,
                recorder_widget,
                second_peak_ratio=self.second_peak_ratio,
                ignore_frequencies=self.ignore_frequencies)

    def check_correct_audio_node_selected(self):
        """Checks the node selected by Cras is correct."""
        # Selects and checks the node selected by cras is correct.
        audio_test_utils.check_and_set_chrome_active_node_types(
                self.facade, self.audio_nodes[0][0], self.audio_nodes[1][0])
        audio_test_utils.check_audio_nodes(self.facade, self.audio_nodes)

    def play_reboot_play_and_record(self, source_widget, recorder_widget):
        """Play audio, then reboot, and play and record.

        @param source_widget: source widget to play with
        @param recorder_widget: recorder widget to record with

        """
        self.play_and_record(source_widget)

        # Disconnecs audio bus so Cros device can detects plugger correctly
        # when the test involes plugger.
        # For case where audio bus is used but no plugger is used, it is no
        # harm to disconnect audio bus and reconnect it.
        if self.use_audio_bus:
            logging.info('Disconnecting audio bus before reboot')
            self.widget_link.disconnect_audio_bus()

        self.host.reboot()
        utils.poll_for_condition(
                condition=self.factory.ready,
                timeout=self.PRC_RECONNECT_TIMEOUT,
        )
        logging.debug('After reboot')

        audio_test_utils.dump_cros_audio_logs(self.host, self.facade,
                                              self.resultsdir, 'after_reboot')

        self.check_correct_audio_node_selected()

        if self.use_audio_bus:
            logging.info('Reconnecting audio bus after reboot before playback')
            self.widget_link.reconnect_audio_bus()

        audio_test_utils.dump_cros_audio_logs(self.host, self.facade,
                                              self.resultsdir,
                                              'after_bus_reconnect')

        self.play_and_record(source_widget, recorder_widget)

    def run_once(self,
                 host,
                 golden_data,
                 audio_nodes,
                 bind_from=None,
                 bind_to=None,
                 source=None,
                 recorder=None,
                 is_internal=False,
                 cfm_speaker=False):
        """Runs the test main workflow.

        @param host: A host object representing the DUT.
        @param golden_data: audio file and low pass filter frequency
           the audio file should be test data defined in audio_test_data
        @param audio_nodes: audio nodes supposed to be selected
        @param bind_from: audio originating entity to be binded
            should be defined in chameleon_audio_ids
        @param bind_to: audio directed_to entity to be binded
            should be defined in chameleon_audio_ids
        @param source: source widget entity
            should be defined in chameleon_audio_ids
        @param recorder: recorder widget entity
            should be defined in chameleon_audio_ids
        @param is_internal: whether internal audio is tested flag
        @param cfm_speaker: whether cfm_speaker's audio is tested which is an
            external USB speaker on CFM (ChromeBox For Meetings) devices.

        """
        if ((bind_from == chameleon_audio_ids.CrosIds.HEADPHONE
             or bind_to == chameleon_audio_ids.CrosIds.EXTERNAL_MIC)
                    and not audio_test_utils.has_audio_jack(self.host)):
            raise error.TestNAError(
                    'No audio jack for the DUT.'
                    ' Confirm swarming bot dimension and control file'
                    ' dependency for audio jack is matching.'
                    ' For new boards, has_audio_jack might need to be updated.'
            )

        if (recorder == chameleon_audio_ids.CrosIds.INTERNAL_MIC and
            (not cfm_speaker
             and not audio_test_utils.has_internal_microphone(host))):
            return

        if (source == chameleon_audio_ids.CrosIds.SPEAKER
                    and (not cfm_speaker
                         and not audio_test_utils.has_internal_speaker(host))):
            return

        self.audio_nodes = audio_nodes
        self.golden_file, self.low_pass_freq = golden_data
        widget_factory = chameleon_audio_helper.AudioWidgetFactory(
                self.factory, host)
        self.widget_link = None
        self.use_audio_bus = False

        self.second_peak_ratio = audio_test_utils.get_second_peak_ratio(
                source_id=source, recorder_id=recorder)

        self.ignore_frequencies = None
        if (source == chameleon_audio_ids.CrosIds.SPEAKER
                    or bind_to == chameleon_audio_ids.CrosIds.EXTERNAL_MIC):
            self.ignore_frequencies = [50, 60]

        # Two widgets are binded in the factory if necessary
        binder_widget = None
        bind_from_widget = None
        bind_to_widget = None
        if bind_from != None and bind_to != None:
            bind_from_widget = widget_factory.create_widget(bind_from)
            bind_to_widget = widget_factory.create_widget(bind_to)
            binder_widget = widget_factory.create_binder(
                    bind_from_widget, bind_to_widget)
            self.widget_link = binder_widget.get_link()
            if isinstance(self.widget_link, audio_widget_link.AudioBusLink):
                self.use_audio_bus = True

        # Additional widgets that could be part of the factory
        if source == None:
            source_widget = bind_from_widget
        else:
            source_widget = widget_factory.create_widget(source)
        if recorder == None:
            recorder_widget = bind_to_widget
        else:
            recorder_widget = widget_factory.create_widget(recorder)

        # Selects and checks the node selected by cras is correct.
        audio_test_utils.check_and_set_chrome_active_node_types(
                self.facade, audio_nodes[0][0], audio_nodes[1][0])

        # Play only, reboot, then play and record.
        if binder_widget != None:
            with chameleon_audio_helper.bind_widgets(binder_widget):
                time.sleep(self.DELAY_AFTER_BINDING)
                self.play_reboot_play_and_record(source_widget,
                                                 recorder_widget)
        else:
            self.play_reboot_play_and_record(source_widget, recorder_widget)

        self.save_and_check_data(recorder_widget)
