# Copyright 2014 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 shutil
import time

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

_STRESS_ITERATIONS = 100 # Total number of iterations.
_MAX_OPENED_TAB = 20     # Max number of tabs open and playing audio.
_RETAIN_TAB = 5          # In case we hit the _MAX_OPENED_TAB limit,
                         # close all except last 5 tabs.
_MAX_TABS_TO_OPEN = 10   # Max number of tabs can be opened in one iteration.
_CRASH_PATH = '/var/spool/crash'


class audio_ActiveStreamStress(test.test):
    """Verifies the active audio streams."""

    version = 1

    _active_stream_count = 0
    _existing_cras_reports = []
    _cr = None
    # TODO(rohitbm): add more(including video) file types and download them from gs://.
    _streams = ('audio.mp3', 'audio.wav', 'audio.m4a')
    _stream_index = 0
    _tab_count = 0

    def run_once(self):

        # Collect existing cras crash reports.
        self._existing_cras_reports = self.collect_cras_crash()

        with chrome.Chrome() as self._cr:
            self._cr.browser.SetHTTPServerDirectories(self.bindir)
            self.push_new_stream(self._cr.browser.tabs[0])
            # TODO(rohitbm): decide whether to perform verification on each
            # open/close or at end of the iteration.
            self.verify_active_streams()
            push_count = 0
            pop_count = 0

            # Stress test logic:
            # Test runs for n number of iterations. For one iteration,
            # a = random(10) tabs(streams) are created and
            # b = random(a) tabs are closed. If the next iteration finds that,
            # total number of opened tabs are more than _MAX_OPENED_TAB,
            # test will close (total opened tabs - 5) tabs.
            # This will balance number of opened tabs and will allow to close
            # tabs in a control manner.

            for count in xrange(1, _STRESS_ITERATIONS):
                if self._tab_count > _MAX_OPENED_TAB:
                     for i in xrange(1, (self._tab_count - _RETAIN_TAB)):
                         pop_count += 1
                         self.pop_stream()
                         logging.info('Total streams closed: %d', pop_count)
                random_tab = random.randint(1, 10)
                for i in xrange(1, random_tab):
                    push_count += 1
                    self.push_new_stream(self._cr.browser.tabs.New())
                    logging.info('Total new streams created: %d', push_count)
                time.sleep(5) # Delay for active streams to play.
                for i in xrange(1, random.randint(1, random_tab)):
                    pop_count += 1
                    self.pop_stream()
                    logging.info('Total streams closed: %d', pop_count)


    def get_stream_index(self):
        if self._stream_index == len(self._streams):
            # Reset the stream index if the index reached to the end.
            self._stream_index = 0
        return self._stream_index


    def push_new_stream(self, tab):
        """Starts next audio stream from self._streams list.

        @param tab: tab to open an audio stream.
        """
        self._tab_count += 1
        tab.Navigate(self._cr.browser.http_server.UrlOf(
                    os.path.join(self.bindir,
                                 self._streams[self.get_stream_index()])))
        tab.ExecuteJavaScript(
                "document.getElementsByTagName('video')[0].loop=true")
        # TODO(rohitbm): add playback verification.
        self._stream_index += 1
        self._active_stream_count += 1
        time.sleep(1) # Adding a delay so cras can update the active count.
        self.verify_active_streams()


    def pop_stream(self):
        """Turns off the first available stream by closing the first tab."""
        if len(self._cr.browser.tabs) > 0:
            self._cr.browser.tabs[0].Close()
            self._tab_count -= 1
            self._active_stream_count -= 1
        time.sleep(1) # Adding delay so cras can update the active count.
        self.verify_active_streams()


    def verify_active_streams(self):
        """Verifies test active audio streams with cras active streams."""
        cras_stream_count = cras_utils.get_active_stream_count()
        if self._active_stream_count != cras_stream_count:
            cras_crash_reports = self.collect_cras_crash()
            new_reports = list(set(cras_crash_reports) -
                               set(self._existing_cras_reports))
            error_msg = ('Active stream count: %d is not matching with '
                         'cras active stream count: %d. '
                         'Number of cras crashes %d : %s' %
                         (self._active_stream_count, cras_stream_count,
                         len(new_reports), new_reports))
            raise error.TestError(error_msg)


    def collect_cras_crash(self):
        """Check for cras crashes.

        @return a list of cras crash reports found.
        """

        crash_reports = []
        if not os.path.isdir(_CRASH_PATH):
            logging.debug('No cras crash detected!')
        else:
            cras_reports = os.listdir(_CRASH_PATH)
            crash_reports = [report for report in cras_reports
                             if report.startswith('cras')]
        return crash_reports
