# Copyright 2020 The Chromium 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 collections
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.common_lib.cros import chrome
from autotest_lib.client.cros import constants as cros_constants
from autotest_lib.client.cros.audio import audio_helper
from autotest_lib.client.cros.audio import audio_test_data
from autotest_lib.client.cros.audio import check_quality
from autotest_lib.client.cros.audio import cmd_utils
from autotest_lib.client.cros.audio import cras_utils
from autotest_lib.client.cros.multimedia import audio_facade_native


CheckQualityArgsClass = collections.namedtuple(
        'args_type', ['filename', 'rate', 'channel', 'bit_width'])


class audio_AudioInputGain(audio_helper.cras_rms_test):
    """Verifies input capture gain of chrome.audio API."""
    version = 1

    ALOOP_CRAS_NODE_TYPE = 'ALSA_LOOPBACK'
    ALOOP_MODULE_NAME = 'snd-aloop'
    CAPTURE_DURATION = 1
    LOW_GAIN = 25
    HIGH_GAIN = 75
    EXPECTED_GAIN = 100
    FREQ_TOLERANCE = 1
    GAIN_TOLERANCE = 10

    def run_once(self):
        """Entry point of this test."""
        def cras_playback_record(gain_level):
            """Do capture record at CRAS level.

            @param gain_level: The input gain level.

            @returns: A string for the recorded file path.

            """
            # Sine raw file lasts 5 seconds
            raw_path = os.path.join(self.bindir, '5SEC.raw')
            raw_file = audio_test_data.GenerateAudioTestData(
                    path=raw_path,
                    duration_secs=5,
                    frequencies=[440, 440],
                    volume_scale=0.05)

            recorded_file = os.path.join(self.resultsdir,
                                         'cras_recorded_%d.raw' % gain_level)

            # Note: we've found that a couple of seconds after Chrome is up,
            #       there may be a ~30-second-long output stream sourced from
            #       "What's New In Your Chromebook", and it plays no sound.
            #       Just ignore it and continue testing.
            p = cmd_utils.popen(cras_utils.playback_cmd(raw_file.path))
            try:
                cras_utils.capture(recorded_file,
                                   duration=self.CAPTURE_DURATION)
                # Make sure the audio is still playing.
                if p.poll() != None:
                    raise error.TestError('playback stopped')
            finally:
                cmd_utils.kill_or_log_returncode(p)
                raw_file.delete()
            return recorded_file

        # Check CRAS server is alive. If not, restart it and wait a second to
        # get server ready.
        if utils.get_service_pid('cras') == 0:
            logging.debug('CRAS server is down. Restart it.')
            utils.start_service('cras', ignore_status=True)
            time.sleep(1)

        utils.load_module(self.ALOOP_MODULE_NAME)

        try:
            with chrome.Chrome(
                    extension_paths=[cros_constants.AUDIO_TEST_EXTENSION],
                    autotest_ext=True) as cr:
                audio_facade = audio_facade_native.AudioFacadeNative(cr)
                audio_facade.set_chrome_active_node_type(
                        self.ALOOP_CRAS_NODE_TYPE, self.ALOOP_CRAS_NODE_TYPE)

                rms_value = []
                for gain in [self.LOW_GAIN, self.HIGH_GAIN]:
                    logging.debug('Start testing loopback with gain %d.', gain)
                    audio_facade.set_chrome_active_input_gain(gain)
                    recorded_file = cras_playback_record(gain)
                    args = CheckQualityArgsClass(filename=recorded_file,
                                                 rate=48000,
                                                 channel=1,
                                                 bit_width=16)
                    raw_data, rate = check_quality.read_audio_file(args)
                    checker = check_quality.QualityChecker(raw_data, rate)
                    # The highest frequency recorded would be near 24 Khz
                    # as the max sample rate is 48000 in our tests.
                    # So let's set ignore_high_freq to be 48000.
                    checker.do_spectral_analysis(ignore_high_freq=48000,
                                                 check_quality=False,
                                                 quality_params=None)
                    spectra = checker._spectrals
                    primary_freq = float(spectra[0][0][0])
                    if abs(primary_freq - 440.0) > self.FREQ_TOLERANCE:
                        raise error.TestFail(
                                'Primary feq is beyond the expectation: '
                                'got %.2f, expected 440.00, tolerance %f' %
                                        (primary_freq, self.FREQ_TOLERANCE))
                    rms_value.append(float(spectra[0][0][1]))

                gain = rms_value[1] / rms_value[0]
                if abs(gain - self.EXPECTED_GAIN) > self.GAIN_TOLERANCE:
                    raise error.TestFail(
                        'Gain is beyond the expectation: '
                        'got %.2f, expected %.2f, tolerance %f' %
                                (gain, self.EXPECTED_GAIN, self.GAIN_TOLERANCE))
        finally:
            utils.stop_service('cras', ignore_status=True)
            utils.unload_module(self.ALOOP_MODULE_NAME)
            utils.start_service('cras', ignore_status=True)
