# Copyright 2019 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 dbus
import logging
import os
import re
import subprocess
import time

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

_STREAM_TYPE_INPUT_APM = 0
_STREAM_TYPE_OUTPUT = 1

class audio_CrasDevSwitchStress(test.test):
    """
    Checks if output buffer will drift to super high level when
    audio devices switch repeatedly.
    """
    version = 1
    _LOOP_COUNT = 150
    _INPUT_BUFFER_LEVEL = '.*?READ_AUDIO.*?dev:(\d+).*hw_level.*?(\d+).*?'
    _OUTPUT_BUFFER_LEVEL = '.*?FILL_AUDIO.*?dev:(\d+).*hw_level.*?(\d+).*?'
    _CHECK_PERIOD_TIME_SECS = 0.5
    _SILENT_OUTPUT_DEV_ID = 2
    _STREAM_BLOCK_SIZE = 480

    """
    Buffer level of input device should stay between 0 and block size.
    Buffer level of output device should between 1 to 2 times of block size.
    Device switching sometimes cause the buffer level to grow more then
    the ideal range, so we use tripple block size here.
    """
    _INPUT_BUFFER_DRIFT_CRITERIA = 3 * _STREAM_BLOCK_SIZE
    _OUTPUT_BUFFER_DRIFT_CRITERIA = 3 * _STREAM_BLOCK_SIZE

    def cleanup(self):
        """Remove all streams for testing."""
        if self._streams:
            # Clean up all streams.
            while len(self._streams) > 0:
                self._streams[0].kill()
                self._streams.remove(self._streams[0])

        super(audio_CrasDevSwitchStress, self).cleanup()

    def _new_stream(self, stream_type, node_pinned):
        """
        Runs new stream by cras_test_client.
        Args:
            stream_type: _STREAM_TYPE_INPUT_APM or _STREAM_TYPE_OUTPUT
            node_pinned: if not None then create the new stream that
                pinned to this node.
        Returns:
            New process that runs a CRAS client stream.
        """
        if stream_type == _STREAM_TYPE_INPUT_APM:
            cmd = ['cras_test_client', '--capture_file', '/dev/null',
                   '--effects', 'aec']
        else:
            cmd = ['cras_test_client', '--playback_file', '/dev/zero']

        cmd += ['--block_size', str(self._STREAM_BLOCK_SIZE)]

        if node_pinned and node_pinned['Id']:
            dev_id = node_pinned['Id'] >> 32
            if stream_type == _STREAM_TYPE_INPUT_APM:
                if node_pinned['IsInput']:
                   cmd += ['--pin_device', str(dev_id)]
            elif not node_pinned['IsInput']:
                    cmd += ['--pin_device', str(dev_id)]

        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 _get_buffer_level(self, match_str, dev_id):
        """
        Gets a rough number about current buffer level.

        Args:
            match_str: regular expression to match device buffer level.
            dev_id: audio device id in CRAS.

        Returns:
            The current 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:
                if dev_id != int(search.group(1)):
                    continue
                tmp = int(search.group(2))
                if tmp > buffer_level:
                    buffer_level = tmp
        return buffer_level

    def _check_buffer_level(self, node):
        """Checks if current buffer level of node stay in criteria."""
        if node['IsInput']:
            match_str = self._INPUT_BUFFER_LEVEL
            criteria = self._INPUT_BUFFER_DRIFT_CRITERIA
        else:
            match_str = self._OUTPUT_BUFFER_LEVEL
            criteria = self._OUTPUT_BUFFER_DRIFT_CRITERIA

        dev_id = node['Id'] >> 32
        buffer_level = self._get_buffer_level(match_str, dev_id)

        logging.debug("Max buffer level: %d on dev %d", buffer_level, dev_id)
        if buffer_level > criteria:
            self._dump_audio()
            raise error.TestFail('Buffer level %d drift too high on %s node'
                                 ' with dev id %d' %
                                 (buffer_level, node['Type'], dev_id))

    def _get_cras_pid(self):
        """Gets the pid of CRAS, used to check if CRAS crashes and respawn."""
        pid = utils.system_output('pgrep cras$ 2>&1', retain_output=True,
                                  ignore_status=True).strip()
        try:
            pid = int(pid)
        except ValueError, e:  # empty or invalid string
            raise error.TestFail('CRAS not running')

    def _switch_to_node(self, node):
        """
        Switches CRAS input or output active node to target node.
        Args:
            node: if not None switch CRAS input/output active node to it
        """
        if node == None:
            return
        if node['IsInput']:
            cras_utils.set_active_input_node(node['Id'])
        else:
            cras_utils.set_active_output_node(node['Id'])

    def run_once(self, type_a=None, type_b=None, pinned_type=None):
        """
        Setup the typical streams used for hangout, one input stream with APM
        plus an output stream. If pinned_type is not None, set up an additional
        stream that pinned to the first node of pinned_type.
        The test repeatedly switch active nodes between the first nodes of
        type_a and type_b to verify there's no crash and buffer level stay
        in reasonable range.

        Args:
            type_a: node type to match a CRAS node
            type_b: node type to match a CRAS node
            pinned_type: node type to match a CRAS node
        """
        node_a = None
        node_b = None
        node_pinned = None
        self._streams = []

        cras_pid = self._get_cras_pid()

        try:
            nodes = cras_utils.get_cras_nodes()
        except dbus.DBusException as e:
            logging.error("Get CRAS nodes failure.");
            raise error.TestFail("No reply from CRAS for get nodes request.")

        for node in nodes:
            if type_a and node['Type'] == type_a:
                node_a = node
            elif type_b and node['Type'] == type_b:
                node_b = node

            if pinned_type and node['Type'] == pinned_type:
                node_pinned = node

        if not (node_a and node_b):
            raise error.TestNAError("No output nodes pair to switch.")

        if node_pinned:
            if node_pinned['IsInput']:
                self._streams.append(
                        self._new_stream(_STREAM_TYPE_INPUT_APM, node_pinned))
            else:
                self._streams.append(
                        self._new_stream(_STREAM_TYPE_OUTPUT, node_pinned))

        self._streams.append(self._new_stream(_STREAM_TYPE_OUTPUT, None))
        self._streams.append(self._new_stream(_STREAM_TYPE_INPUT_APM, None))

        loop_count = 0
        past_time = time.time()

        try:
            while loop_count < self._LOOP_COUNT:
                # Switch active input/output node in each loop.
                if loop_count % 2 == 0:
                    self._switch_to_node(node_a)
                else:
                    self._switch_to_node(node_b)

                time.sleep(0.2)
                now = time.time()

                # Check buffer level.
                if now - past_time > self._CHECK_PERIOD_TIME_SECS:
                    past_time = now
                    self._check_buffer_level(node_a)
                    self._check_buffer_level(node_b)

                loop_count += 1
                if cras_pid != self._get_cras_pid():
                    raise error.TestFail("CRAS crashed and respawned.")
        except dbus.DBusException as e:
            logging.exception(e)
            raise error.TestFail("CRAS may have crashed.")
