# 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/glbench/bin
# 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 confidence check for GL/GLES.
    """
    version = 1

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

    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('/usr/local/', 'glbench', 'bin', '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')
