# Copyright (c) 2012 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 glob, logging, os

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import base_utils, error
from autotest_lib.client.cros import cros_ui_test

def get_percent_difference(file1, file2):
    """
    Performs byte-by-byte comparison of two files, given by their paths |file1|
    and |file2|.  Returns difference as a percentage of the total file size.  If
    one file is larger than the other, the difference is a percentage of
    |file1|.
    """
    files = (file1, file2)
    sizes = {}
    for filename in files:
        if not os.path.exists(filename):
            raise error.TestFail('Could not find file \'%s\'.' % filename)
        sizes[filename] = os.path.getsize(filename)
        if sizes[filename] == 0:
            raise error.TestFail('File \'%s\' has zero size.' % filename)

    diff_bytes = int(utils.system_output('cmp -l %s %s | wc -l' % files))

    return round(100. * diff_bytes / sizes[file1])


class graphics_VTSwitch(cros_ui_test.UITest):
    version = 1
    # TODO(crosbug.com/36417): Need to handle more than one display screen.

    def setup(self):
        self.job.setup_dep(['gfxtest'])


    def run_once(self,
                 num_iterations=2,
                 similarity_percent_threshold=95,
                 difference_percent_threshold=5):
        self._num_errors = 0
        keyvals = {}

        # Make sure we start in VT1
        if not self._switch_to_vt(1):
            raise error.TestFail('Could not switch to VT1')

        # Take screenshot of sign-in screen.
        logged_out_screenshot = self._take_current_vt_screenshot()

        keyvals['num_iterations'] = num_iterations

        # Go to VT2 and take a screenshot.
        if not self._switch_to_vt(2):
            raise error.TestFail('Could not switch to VT2')
        vt2_screenshot = self._take_current_vt_screenshot()

        # Make sure VT1 and VT2 are sufficiently different.
        diff = get_percent_difference(logged_out_screenshot, vt2_screenshot)
        keyvals['percent_initial_VT1_VT2_difference'] = diff
        if not diff >= difference_percent_threshold:
            self._num_errors += 1
            logging.error('VT1 and VT2 screenshots only differ by ' + \
                          '%d %%: %s vs %s' %
                          (diff, logged_out_screenshot, vt2_screenshot))

        num_identical_vt1_screenshots = 0
        num_identical_vt2_screenshots = 0
        max_vt1_difference_percent = 0
        max_vt2_difference_percent = 0

        # Repeatedly switch between VT1 and VT2.
        for iteration in xrange(num_iterations):
            logging.info('Iteration #%d' % iteration)

            # Go to VT1 and take a screenshot.
            self._switch_to_vt(1)
            current_vt1_screenshot = self._take_current_vt_screenshot()

            # Make sure the current VT1 screenshot is the same as (or similar
            # to) the original login screen screenshot.
            diff = get_percent_difference(logged_out_screenshot,
                                          current_vt1_screenshot)
            if not diff < similarity_percent_threshold:
                max_vt1_difference_percent = \
                    max(diff, max_vt1_difference_percent)
                self._num_errors += 1
                logging.error('VT1 screenshots differ by %d %%: %s vs %s' %
                              (diff, logged_out_screenshot,
                               current_vt1_screenshot))
            else:
                num_identical_vt1_screenshots += 1

            # Go to VT2 and take a screenshot.
            self._switch_to_vt(2)
            current_vt2_screenshot = self._take_current_vt_screenshot()

            # Make sure the current VT2 screenshot is the same as (or similar
            # to) the first VT2 screenshot.
            diff = get_percent_difference(vt2_screenshot,
                                          current_vt2_screenshot)
            if not diff <= similarity_percent_threshold:
                max_vt2_difference_percent = \
                    max(diff, max_vt2_difference_percent)
                self._num_errors += 1
                logging.error(
                    'VT2 screenshots differ by %d %%: %s vs %s' %
                    (diff, vt2_screenshot, current_vt2_screenshot))
            else:
                num_identical_vt2_screenshots += 1

        # Now make sure we can login again.
        self._switch_to_vt(1)
        self.login()
        if not self.logged_in():
            logging.error('Cannot log in after repeated VT switching.')

        keyvals['percent_VT1_screenshot_max_difference'] = \
            max_vt1_difference_percent
        keyvals['percent_VT2_screenshot_max_difference'] = \
            max_vt2_difference_percent
        keyvals['num_identical_vt1_screenshots'] = num_identical_vt1_screenshots
        keyvals['num_identical_vt2_screenshots'] = num_identical_vt2_screenshots

        self.write_perf_keyval(keyvals)

        if self._num_errors > 0:
            raise error.TestError('Test failed with %d errors' %
                                  self._num_errors)


    def cleanup(self):
        # Return to VT1 when done.  Ideally, the screen should already be in VT1
        # but the test might fail and terminate while in VT2.
        self._switch_to_vt(1)

        if self.logged_in():
            self.logout()


    def _take_current_vt_screenshot(self):
        """
        Captures a screenshot of the current VT screen in BMP format.
        Returns the path of the screenshot file.
        """
        current_vt = int(utils.system_output('fgconsole'))
        extension = 'bmp'

        # In VT1, X is running so use the screenshot function in cros_ui_test.
        if current_vt == 1:
            return self.take_screenshot('graphics_VTSwitch_VT1', extension)

        # Otherwise, grab the framebuffer using DRM.
        prefix = 'graphics_VTSwitch_VT2'
        next_index = len(glob.glob(
            os.path.join(self.resultsdir, '%s-*.%s' % (prefix, extension))))
        filename = '%s-%d.%s' % (prefix, next_index, extension)
        output_path = os.path.join(self.resultsdir, filename)
        return self._take_drm_screenshot(output_path)


    def _take_drm_screenshot(self, output_path):
        autotest_deps_path = os.path.join(self.autodir, 'deps')
        getfb_path = os.path.join(autotest_deps_path, 'gfxtest', 'getfb')
        output = utils.system_output('%s %s.rgba' % (getfb_path, output_path))
        for line in output.split('\n'):
            # Parse the getfb output for info about framebuffer size.  The line
            # should looks omething like:
            #   Framebuffer info: 1024x768, 32bpp
            if line.startswith('Framebuffer info:'):
                size = line.split(':')[1].split(',')[0].strip()
                break
        utils.system('convert -depth 8 -size %s %s.rgba %s' %
                     (size, output_path, output_path))

        logging.info('Saving screenshot to %s' % output_path)
        return output_path


    def _switch_to_vt(self, vt):
        """
        Switches to virtual terminal given by |vt| (1, 2, etc) and checks that
        the switch was successful by calling fgconsole.

        Returns True if fgconsole returned the new vt number, False otherwise.
        """
        utils.system_output('chvt %d' % vt)

        # Verify that the VT switch was successful.
        current_vt = base_utils.wait_for_value(
            lambda: int(utils.system_output('fgconsole')),
            expected_value=vt)
        if vt != current_vt:
            self._num_errors += 1
            logging.error('Current VT %d does not match expected VT %d' %
                          (current_vt, vt))
            return False
        logging.info('Switched to VT%d' % vt)
        return True
