# Copyright (c) 2010 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 os
import logging

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 service_stopper
from autotest_lib.client.cros.graphics import graphics_utils

# to run this test manually on a test target
# ssh root@machine
# cd /usr/local/autotest/deps/glbench
# stop ui
# ./windowmanagertest --screenshot1_sec 2 --screenshot2_sec 1 --cooldown_sec 1 \
#    --screenshot1_cmd "screenshot screenshot1_generated.png" \
#    --screenshot2_cmd "screenshot screenshot2_generated.png"
# start ui


class graphics_Sanity(graphics_utils.GraphicsTest):
    """
    This test is meant to be used as a quick sanity check for GL/GLES.
    """
    version = 1

    # None-init vars used by cleanup() here, in case setup() fails
    _services = None

    def setup(self):
        self.job.setup_dep(['glbench'])
        dep = 'glbench'
        dep_dir = os.path.join(self.autodir, 'deps', dep)
        self.job.install_pkg(dep, 'dep', dep_dir)

    def cleanup(self):
        super(graphics_Sanity, self).cleanup()
        if self._services:
            self._services.restore_services()

    def test_something_on_screen(self):
        """Check if something is drawn on screen: i.e. not a black screen.

        @raises TestFail if we cannot determine there was something on screen.
        """

        def can_take_screenshot():
            """Check that taking a screenshot can succeed.

            There are cases when trying to take a screenshot on the device
            fails. e.g. the display has gone to sleep, we have logged out and
            the UI has not come back up yet etc.
            """
            try:
                graphics_utils.take_screenshot(self.resultsdir,
                                               'temp screenshot')
                return True
            except:
                return False

        utils.poll_for_condition(
            can_take_screenshot,
            sleep_interval=1,
            desc='Failed to take a screenshot. There may be an issue with this '
            'ChromeOS image.')

        w, h = graphics_utils.get_internal_resolution()
        megapixels = (w * h) / 1000000
        filesize_threshold = 15 * megapixels
        screenshot1 = graphics_utils.take_screenshot(self.resultsdir,
                                                     'oobe or signin')

        with chrome.Chrome() as cr:
            tab = cr.browser.tabs[0]
            tab.Navigate('chrome://settings')
            tab.WaitForDocumentReadyStateToBeComplete()

            screenshot2 = graphics_utils.take_screenshot(
                self.resultsdir, 'settings page')

        for screenshot in [screenshot1, screenshot2]:
            file_size_kb = os.path.getsize(screenshot) / 1000

            # Use compressed file size to tell if anything is on screen.
            if file_size_kb > filesize_threshold:
                return

        raise error.TestFail(
            'Screenshot filesize is smaller than expected(%s <= %s). This '
            'indicates that there is nothing on screen. This ChromeOS image '
            'could be unusable. Check the screenshot in the results folder.' %
            (file_size_kb, filesize_threshold))

    def test_generated_screenshots_match_expectation(self):
        """Draws a texture with a soft ellipse twice and captures each image.
        Compares the output fuzzily against reference images.
        """
        self._services = service_stopper.ServiceStopper(['ui'])
        self._services.stop_services()

        screenshot1_reference = os.path.join(self.bindir,
                                             'screenshot1_reference.png')
        screenshot1_generated = os.path.join(self.resultsdir,
                                             'screenshot1_generated.png')
        screenshot1_resized = os.path.join(self.resultsdir,
                                           'screenshot1_generated_resized.png')
        screenshot2_reference = os.path.join(self.bindir,
                                             'screenshot2_reference.png')
        screenshot2_generated = os.path.join(self.resultsdir,
                                             'screenshot2_generated.png')
        screenshot2_resized = os.path.join(self.resultsdir,
                                           'screenshot2_generated_resized.png')

        exefile = os.path.join(self.autodir, 'deps/glbench/windowmanagertest')

        # Delay before screenshot: 1 second has caused failures.
        options = ' --screenshot1_sec 2'
        options += ' --screenshot2_sec 1'
        options += ' --cooldown_sec 1'
        # perceptualdiff can handle only 8 bit images.
        screenshot_cmd = ' "screenshot %s"'
        options += ' --screenshot1_cmd' + screenshot_cmd % screenshot1_generated
        options += ' --screenshot2_cmd' + screenshot_cmd % screenshot2_generated

        cmd = exefile + ' ' + options
        utils.run(
            cmd, stdout_tee=utils.TEE_TO_LOGS, stderr_tee=utils.TEE_TO_LOGS)

        convert_cmd = ('convert -channel RGB -colorspace RGB -depth 8'
                       " -resize '100x100!' %s %s")
        utils.system(convert_cmd % (screenshot1_generated, screenshot1_resized))
        utils.system(convert_cmd % (screenshot2_generated, screenshot2_resized))
        os.remove(screenshot1_generated)
        os.remove(screenshot2_generated)

        diff_cmd = 'perceptualdiff -verbose %s %s'
        utils.system(diff_cmd % (screenshot1_reference, screenshot1_resized))
        utils.system(diff_cmd % (screenshot2_reference, screenshot2_resized))

    def run_once(self):
        if graphics_utils.get_display_resolution() is None:
            logging.warning('Skipping test because there is no screen')
            return
        self.add_failures('graphics_Sanity')
        self.wake_screen_with_keyboard()
        self.test_something_on_screen()
        self.test_generated_screenshots_match_expectation()
        self.remove_failures('graphics_Sanity')
