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

import logging
import tempfile
import time

import common
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import site_utils
from autotest_lib.client.common_lib.feedback import client
from autotest_lib.server import test


# The amount of time to wait when producing silence (i.e. no playback).
_SILENCE_DURATION_SECS = 5

# Number of channels to generate.
_DEFAULT_NUM_CHANNELS = 1
# Sine wave sample rate (48kHz).
_DEFAULT_SAMPLE_RATE = 48000
# Sine wave default sample format is signed 16-bit PCM (two bytes).
_DEFAULT_SAMPLE_WIDTH = 2
# Default sine wave frequency.
_DEFAULT_SINE_FREQUENCY = 440
# Default duration of the sine wave in seconds.
_DEFAULT_DURATION_SECS = 10

class brillo_PlaybackAudioTest(test.test):
    """Verify that basic audio playback works."""
    version = 1

    def __init__(self, *args, **kwargs):
        super(brillo_PlaybackAudioTest, self).__init__(*args, **kwargs)
        self.host = None


    def _get_playback_cmd(self, method, dut_play_file):
        """Get the playback command to execute based on the playback method.

        @param method: A string specifiying which method to use.
        @param dut_play_file: A string containing the path to the file to play
                              on the DUT.
        @return: A string containing the command to play audio using the
                 specified method.

        @raises TestError: Invalid playback method.
        """
        if dut_play_file:
            return 'su root slesTest_playFdPath %s 0' % dut_play_file
        if method == 'libmedia':
            return 'brillo_audio_test --playback --libmedia --sine'
        elif method == 'stagefright':
            return 'brillo_audio_test --playback --stagefright --sine'
        elif method == 'opensles':
            return 'slesTest_sawtoothBufferQueue'
        else:
            raise error.TestError('Test called with invalid playback method.')


    def test_playback(self, fb_query, playback_cmd, sample_width, sample_rate,
                      num_channels, play_file_path=None):
        """Performs a playback test.

        @param fb_query: A feedback query.
        @param playback_cmd: The playback generating command, or None for no-op.
        @param play_file_path: A string of the path to the file being played.
        @param sample_width: Sample width to test playback at.
        @param sample_rate: Sample rate to test playback at.
        @param num_channels: Number of channels to test playback with.
        """
        fb_query.prepare(sample_width=sample_width,
                         sample_rate=sample_rate,
                         duration_secs=self.duration_secs,
                         num_channels=num_channels)
        if playback_cmd:
            self.host.run(playback_cmd)
        else:
            time.sleep(_SILENCE_DURATION_SECS)
        if play_file_path:
            fb_query.validate(audio_file=play_file_path)
        else:
            fb_query.validate()


    def test_audio(self, fb_client, playback_method, sample_rate, sample_width,
                   num_channels):
        """Test audio playback with the given parameters.

        @param fb_client: A feedback client implementation.
        @param playback_method: A string representing a playback method to use.
                                Either 'opensles', 'libmedia', or 'stagefright'.
        @param sample_rate: Sample rate to test playback at.
        @param sample_width: Sample width to test playback at.
        @param num_channels: Number of channels to test playback with.
        """
        logging.info('Testing silent playback')
        fb_query = fb_client.new_query(client.QUERY_AUDIO_PLAYBACK_SILENT)
        self.test_playback(fb_query=fb_query,
                           playback_cmd=None,
                           sample_rate=sample_rate,
                           sample_width=sample_width,
                           num_channels=num_channels)

        dut_play_file = None
        host_filename = None
        if self.use_file:
           host_filename, dut_play_file = site_utils.generate_sine_file(
                   self.host, num_channels, sample_rate, sample_width,
                   self.duration_secs, _DEFAULT_SINE_FREQUENCY, self.temp_dir)

        logging.info('Testing audible playback')
        fb_query = fb_client.new_query(client.QUERY_AUDIO_PLAYBACK_AUDIBLE)
        playback_cmd = self._get_playback_cmd(playback_method, dut_play_file)

        self.test_playback(fb_query=fb_query,
                           playback_cmd=playback_cmd,
                           sample_rate=sample_rate,
                           sample_width=sample_width,
                           num_channels=num_channels,
                           play_file_path=host_filename)


    def run_once(self, host, fb_client, playback_method, use_file=False,
                 sample_widths_arr=[_DEFAULT_SAMPLE_WIDTH],
                 sample_rates_arr=[_DEFAULT_SAMPLE_RATE],
                 num_channels_arr=[_DEFAULT_NUM_CHANNELS],
                 duration_secs=_DEFAULT_DURATION_SECS):
        """Runs the test.

        @param host: A host object representing the DUT.
        @param fb_client: A feedback client implementation.
        @param playback_method: A string representing a playback method to use.
                                Either 'opensles', 'libmedia', or 'stagefright'.
        @param use_file: Use a file to test audio. Must be used with
                         playback_method 'opensles'.
        @param sample_widths_arr: Array of sample widths to test playback at.
        @param sample_rates_arr: Array of sample rates to test playback at.
        @param num_channels_arr: Array of number of channels to test playback
                                 with.
        @param duration_secs: Duration to play file for.
        """
        self.host = host
        self.duration_secs = duration_secs
        self.use_file = use_file
        self.temp_dir = tempfile.mkdtemp(dir=fb_client.tmp_dir)
        failed_params = []
        with fb_client.initialize(self, host):
            for sample_rate in sample_rates_arr:
                for sample_width in sample_widths_arr:
                    for num_channels in num_channels_arr:
                        logging.info('Running test with the following params:')
                        logging.info('Sample rate: %d', sample_rate)
                        logging.info('Sample width: %d', sample_width)
                        logging.info('Number of channels: %d', num_channels)

                        try:
                            self.test_audio(fb_client=fb_client,
                                            playback_method=playback_method,
                                            sample_rate=sample_rate,
                                            sample_width=sample_width,
                                            num_channels=num_channels)
                        except error.TestFail:
                            logging.info('Test failed.')
                            failed_params.append((sample_rate, sample_width,
                                                  num_channels))
                        finally:
                            # Sleep to avoid conflict between different tests.
                            time.sleep(duration_secs)

        if failed_params == []:
            logging.info('All tests successfully passed.')
        else:
            logging.error('The following combinations failed:')
            for param in failed_params:
                logging.error('Sample rate: %i, Sample width: %i, Num Channels '
                              '%i', param[0], param[1], param[2])
            raise error.TestFail('Some of the tests failed to pass.')
