# Copyright (c) 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 datetime, logging, os, time, shutil

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import file_utils
from autotest_lib.client.common_lib import sequence_utils
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros import constants as cros_constants
from autotest_lib.client.cros.chameleon import chameleon
from autotest_lib.client.cros.chameleon import chameleon_port_finder
from autotest_lib.client.cros.chameleon import chameleon_video_capturer
from autotest_lib.client.cros.image_comparison import publisher
from autotest_lib.client.cros.video import constants
from autotest_lib.client.cros.video import frame_checksum_utils
from autotest_lib.client.cros.video import native_html5_player
from autotest_lib.client.cros.video import helper_logger
from autotest_lib.client.cros.multimedia import local_facade_factory


class video_GlitchDetection(test.test):
    """
    Video playback test using image comparison.

    Captures frames using chameleon and compares them to known golden frames.

    If frames don't match, upload to GS for viewing later.

    """
    version = 2

    @helper_logger.video_log_wrapper
    def run_once(self, source_path, codec, resolution, host, args,
                 collect_only = False):

        board = utils.get_current_board()

        shutil.copy2(constants.VIDEO_HTML_FILEPATH, self.bindir)

        file_utils.make_leaf_dir(constants.TEST_DIR)

        with chrome.Chrome(
                extra_browser_args=helper_logger.chrome_vmodule_flag(),
                extension_paths = [cros_constants.DISPLAY_TEST_EXTENSION],
                autotest_ext=True,
                init_network_controller=True) as cr:

            cr.browser.platform.SetHTTPServerDirectories(self.bindir)
            html_fullpath = os.path.join(self.bindir, 'video.html')
            player = native_html5_player.NativeHtml5Player(
                tab = cr.browser.tabs[0],
                full_url = cr.browser.platform.http_server.UrlOf(html_fullpath),
                video_id = 'video',
                video_src_path = source_path,
                event_timeout = 120)

            chameleon_board = chameleon.create_chameleon_board(host.hostname,
                                                               args)
            display_facade = local_facade_factory.LocalFacadeFactory(
                cr).create_display_facade()

            finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)

            ports = finder.find_all_ports().connected

            logging.debug(finder)

            if not ports:
                raise error.TestError(finder)

            capturer = chameleon_video_capturer.ChameleonVideoCapturer(
                    ports[0], display_facade)

            with capturer:
                player.load_video()

                player.verify_video_can_play()

                display_facade.move_to_display(
                    display_facade.get_first_external_display_id())
                display_facade.set_fullscreen(True)
                # HACK: Unset and reset fullscreen. There is a bug in Chrome
                # that fails to move the window to a correct position.
                # Resetting fullscren helps, check http://crbug.com/574284
                display_facade.set_fullscreen(False)
                display_facade.set_fullscreen(True)
                time.sleep(5)

                box = (0, 0, constants.DESIRED_WIDTH, constants.DESIRED_HEIGHT)

                #TODO: mussa, Revisit once crbug/580736 is fixed
                for n in xrange(constants.NUM_CAPTURE_TRIES):
                    logging.debug('Trying to capture frames. TRY #%d', n + 1)
                    raw_test_checksums = capturer.capture_only(
                        player, max_frame_count = constants.FCOUNT,
                        box = box)

                    raw_test_checksums = [tuple(checksum) for checksum in
                                          raw_test_checksums]

                    overreach_counts = self.overreach_frame_counts(
                            raw_test_checksums,
                            constants.MAX_FRAME_REPEAT_COUNT)

                    if not overreach_counts: # no checksums exceeded threshold
                        break

                    player.pause()
                    player.seek_to(datetime.timedelta(seconds=0))

                else:
                    msg = ('Framecount overreach detected even after %d '
                           'tries. Checksums: %s' % (constants.NUM_CAPTURE_TRIES,
                                                     overreach_counts))
                    raise error.TestFail(msg)


                # produces unique checksums mapped to their occur. indices
                test_checksum_indices = frame_checksum_utils.checksum_indices(
                        raw_test_checksums)

                test_checksums = test_checksum_indices.keys()

                test_indices = test_checksum_indices.values()

                golden_checksums_filepath = os.path.join(
                    constants.TEST_DIR,
                    constants.GOLDEN_CHECKSUMS_FILENAME)

                if collect_only:
                    capturer.write_images(test_indices, constants.TEST_DIR,
                                          constants.IMAGE_FORMAT)

                    logging.debug("Write golden checksum file to %s",
                                  golden_checksums_filepath)

                    with open(golden_checksums_filepath, "w+") as f:
                        for checksum in test_checksums:
                            f.write(' '.join([str(i) for i in checksum]) + '\n')
                    return

                golden_checksums_remote_filepath = os.path.join(
                    constants.GOLDEN_CHECKSUM_REMOTE_BASE_DIR,
                    board,
                    codec + '_' + resolution,
                    constants.GOLDEN_CHECKSUMS_FILENAME)

                file_utils.download_file(golden_checksums_remote_filepath,
                                         golden_checksums_filepath)

                golden_checksums = self.read_checksum_file(
                    golden_checksums_filepath)

                golden_checksum_count = len(golden_checksums)
                test_checksum_count = len(test_checksums)

                eps = constants.MAX_DIFF_TOTAL_FCOUNT
                if golden_checksum_count - test_checksum_count > eps:
                    msg = ('Expecting about %d checksums, received %d. '
                           'Allowed delta is %d') % (
                            golden_checksum_count,
                            test_checksum_count,
                            eps)
                    raise error.TestFail(msg)

                # Some frames might be missing during either golden frame
                # collection or during a test run. Using LCS ensures we
                # ignore a few missing frames while comparing test vs golden

                lcs_len = sequence_utils.lcs_length(golden_checksums,
                                                    test_checksums)

                missing_frames_count = len(golden_checksums) - lcs_len
                unknown_frames_count = len(test_checksums) - lcs_len

                msg = ('# of matching frames : %d. # of missing frames : %d. '
                       '# of unknown test frames : %d. Max allowed # of '
                       'missing frames : %d. # of golden frames : %d. # of '
                       'test_checksums : %d' %(lcs_len, missing_frames_count,
                                               unknown_frames_count,
                                               constants.MAX_NONMATCHING_FCOUNT,
                                               len(golden_checksums),
                                               len(test_checksums)))
                logging.debug(msg)

                if (missing_frames_count + unknown_frames_count >
                        constants.MAX_NONMATCHING_FCOUNT):
                    unknown_frames = set(test_checksums) - set(golden_checksums)

                    store_indices = [test_checksum_indices[c] for c in
                                     unknown_frames]

                    paths = capturer.write_images(store_indices,
                                                  constants.TEST_DIR,
                                                  constants.IMAGE_FORMAT)

                    path_publish = publisher.ImageDiffPublisher(self.resultsdir)
                    path_publish.publish_paths(paths, self.tagged_testname)

                    raise error.TestFail("Too many non-matching frames")


    def overreach_frame_counts(self, checksums, max_frame_repeat_count):
        """
        Checks that captured frames have not exceed the max repeat count.

        @param checksums: list of frame checksums received from chameleon.
        @param max_frame_repeat_count: int. max allowed count.
        @return : dictionary, checksums and their counts

        """

        logging.debug("Verify no frame is repeated more than %d",
                      max_frame_repeat_count)

        counts = frame_checksum_utils.checksum_counts(checksums)
        overreach_counts = {}

        for k, v in counts.iteritems():
            logging.debug("%s : %s", k, v)
            if v > max_frame_repeat_count:
                overreach_counts[k] = v

        return overreach_counts



    def read_checksum_file(self, path):
        """
        Reads the golden checksum file. Each line in file has the format
        w x y z where w x y z is a chameleon frame checksum
        @param path: complete path to the golden checksum file.
        @returns a list of 4-tuples (w x y z).

        """
        checksums = []
        with open(path) as f:
            for line in f:
                checksum = tuple(int(val) for val in line.split())
                checksums.append(checksum)
        return  checksums
