# Lint as: python2, python3
# Copyright 2015 The ChromiumOS Authors
# 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
from autotest_lib.client.cros.chameleon.chameleon import ChameleonPort


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], None)
        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.
        try:
            if self.use_audio_bus:
                logging.info('Disconnecting audio bus before reboot')
                self.widget_link.disconnect_audio_bus()

            if self.host.chameleon.get_platform() == "RASPI":
                ChameleonPort(self.host.chameleon._chameleond_proxy, 9).unplug()
            self.host.reboot()
            utils.poll_for_condition(
                    condition=self.factory.ready,
                    timeout=self.PRC_RECONNECT_TIMEOUT,
            )
            logging.debug('After reboot')
            if self.host.chameleon.get_platform() == "RASPI":
                ChameleonPort(self.host.chameleon._chameleond_proxy, 9).plug()

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

            self.check_correct_audio_node_selected()

        except:
            raise

        finally:
            # Always reconnect after disconnect to prevent wrong snapshot.
            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,
                 blocked_boards=[]):
        """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.
        @blocked_boards: boards to ignore and exit.

        """
        if self.host.get_board().split(':')[1] in blocked_boards:
            raise error.TestNAError('Board NOT APPLICABLE to test!')
        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
                    or recorder == chameleon_audio_ids.CrosIds.INTERNAL_MIC):
            self.ignore_frequencies = [17, 29, 42, 43, 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], None)

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