# 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 os
import random
import re
import subprocess
import time

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.audio import audio_helper

_STREAM_TYPE_INPUT = 0
_STREAM_TYPE_OUTPUT = 1

class audio_CrasStress(test.test):
    """Checks if output buffer will drift to super high level."""
    version = 2
    _MAX_STREAMS = 3
    _LOOP_COUNT = 300
    _INPUT_BUFFER_LEVEL = '.*?READ_AUDIO.*?hw_level.*?(\d+).*?'
    _OUTPUT_BUFFER_LEVEL = '.*?FILL_AUDIO.*?hw_level.*?(\d+).*?'
    _CHECK_PERIOD_TIME_SECS = 1 # Check buffer level every second.

    """
    We only run 1024 and 512 block size streams in this test. So buffer level
    of input device should stay between 0 and 1024. Buffer level of output
    device should between 1024 to 2048. Sometimes it will be a little more.
    Therefore, we set input buffer criteria to 2 * 1024 and output buffer
    criteria to 3 * 1024.
    """
    _RATES = ['48000', '44100']
    _BLOCK_SIZES = ['512', '1024']
    _INPUT_BUFFER_DRIFT_CRITERIA = 2 * 1024
    _OUTPUT_BUFFER_DRIFT_CRITERIA = 3 * 1024

    def _new_stream(self, stream_type):
        """Runs new stream by cras_test_client."""
        if stream_type == _STREAM_TYPE_INPUT:
            cmd = ['cras_test_client', '--capture_file', '/dev/null']
        else:
            cmd = ['cras_test_client', '--playback_file', '/dev/zero']

        cmd += ['--rate', self._RATES[random.randint(0, 1)],
                '--block_size', self._BLOCK_SIZES[random.randint(0, 1)]]

        return subprocess.Popen(cmd)

    def _dump_audio(self):
        log_file = os.path.join(self.resultsdir, "audio_diagnostics.txt")
        with open(log_file, 'w') as f:
            f.write(audio_helper.get_audio_diagnostics())

    def _check_buffer_level(self, stream_type):

        buffer_level = self._get_buffer_level(stream_type)

        if stream_type == _STREAM_TYPE_INPUT:
            logging.debug("Max input buffer level: %d", buffer_level)
            if buffer_level > self._INPUT_BUFFER_DRIFT_CRITERIA:
                self._dump_audio()
                raise error.TestFail('Input buffer level %d drift too high' %
                                     buffer_level)

        if stream_type == _STREAM_TYPE_OUTPUT:
            logging.debug("Max output buffer level: %d", buffer_level)
            if buffer_level > self._OUTPUT_BUFFER_DRIFT_CRITERIA:
                self._dump_audio()
                raise error.TestFail('Output buffer level %d drift too high' %
                                     buffer_level)


    def run_once(self, input_stream=True, output_stream=True):
        """
        Repeatedly add output streams of random configurations and
        remove them to verify if output buffer level would drift.

        @params input_stream: If true, run input stream in the test.
        @params output_stream: If true, run output stream in the test.
        """

        if not input_stream and not output_stream:
            raise error.TestError('Not supported mode.')

        self._streams = []

        loop_count = 0
        past_time = time.time()
        while loop_count < self._LOOP_COUNT:

            # 1 for adding stream, 0 for removing stream.
            add = random.randint(0, 1)
            if len(self._streams) == 0:
                add = 1
            elif len(self._streams) == self._MAX_STREAMS:
                add = 0

            if add == 1:
                # 0 for input stream, 1 for output stream.
                stream_type = random.randint(0, 1)
                if not input_stream:
                    stream_type = _STREAM_TYPE_OUTPUT
                elif not output_stream:
                    stream_type = _STREAM_TYPE_INPUT

                self._streams.append(self._new_stream(stream_type))
            else:
                self._streams[0].kill()
                self._streams.remove(self._streams[0])
                time.sleep(0.1)

            now = time.time()

            # Check buffer level.
            if now - past_time > self._CHECK_PERIOD_TIME_SECS:
                past_time = now
                if input_stream:
                    self._check_buffer_level(_STREAM_TYPE_INPUT)
                if output_stream:
                    self._check_buffer_level(_STREAM_TYPE_OUTPUT)

            loop_count += 1

        # Clean up all streams.
        while len(self._streams) > 0:
            self._streams[0].kill()
            self._streams.remove(self._streams[0])


    def _get_buffer_level(self, stream_type):
        """Gets a rough number about current buffer level.

        @returns: The current buffer level.

        """
        if stream_type == _STREAM_TYPE_INPUT:
            match_str = self._INPUT_BUFFER_LEVEL
        else:
            match_str = self._OUTPUT_BUFFER_LEVEL

        proc = subprocess.Popen(['cras_test_client', '--dump_a'],
                                stdout=subprocess.PIPE)
        output, err = proc.communicate()
        buffer_level = 0
        for line in output.split('\n'):
            search = re.match(match_str, line)
            if search:
                tmp = int(search.group(1))
                if tmp > buffer_level:
                    buffer_level = tmp
        return buffer_level

