# 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.

"""Classes to do screen comparison."""

import logging
import os
import time

from PIL import ImageChops


class ScreenComparer(object):
    """A class to compare two screens.

    Calling its member method compare() does the comparison.

    """

    def __init__(self, capturer1, capturer2, output_dir, pixel_diff_margin,
                 wrong_pixels_margin, skip_if_diff_sizes=False):
        """Initializes the ScreenComparer objects.

        @param capture1: The screen capturer object.
        @param capture2: The screen capturer object.
        @param output_dir: The directory for output images.
        @param pixel_diff_margin: The margin for comparing a pixel. Only
                if a pixel difference exceeds this margin, will treat as a wrong
                pixel. Sets None means using default value by detecting
                connector type.
        @param wrong_pixels_margin: The percentage of margin for wrong pixels.
                The value is in a closed interval [0.0, 1.0]. If the total
                number of wrong pixels exceeds this margin, the check fails.
        @param skip_if_diff_sizes: Skip the comparison if the image sizes are
                different. Used in mirrored test as the internal and external
                screens have different resolutions.
        """
        # TODO(waihong): Support multiple capturers.
        self._capturer1 = capturer1
        self._capturer2 = capturer2
        self._output_dir = output_dir
        self._pixel_diff_margin = pixel_diff_margin
        assert 0.0 <= wrong_pixels_margin <= 1.0
        self._wrong_pixels_margin = wrong_pixels_margin
        self._skip_if_diff_sizes = skip_if_diff_sizes


    def compare(self):
        """Compares the screens.

        @return: None if the check passes; otherwise, a string of error message.
        """
        tags = [self._capturer1.TAG, self._capturer2.TAG]
        images = [self._capturer1.capture(), self._capturer2.capture()]

        if None in images:
            message = ('Failed to capture the screen of %s.' %
                       tags[images.index(None)])
            logging.error(message)
            return message

        # Sometimes the format of images got from X is not RGB,
        # which may lead to ValueError raised by ImageChops.difference().
        # So here we check the format before comparing them.
        for i, image in enumerate(images):
          if image.mode != 'RGB':
            images[i] = image.convert('RGB')

        message = 'Unexpected exception'
        time_str = time.strftime('%H%M%S')
        try:
            # The size property is the resolution of the image.
            if images[0].size != images[1].size:
                message = ('Sizes of images %s and %s do not match: '
                           '%dx%d != %dx%d' %
                           (tuple(tags) + images[0].size + images[1].size))
                if self._skip_if_diff_sizes:
                    logging.info(message)
                    return None
                else:
                    logging.error(message)
                    return message

            size = images[0].size[0] * images[0].size[1]
            max_acceptable_wrong_pixels = int(self._wrong_pixels_margin * size)

            logging.info('Comparing the images between %s and %s...', *tags)
            diff_image = ImageChops.difference(*images)
            histogram = diff_image.convert('L').histogram()

            num_wrong_pixels = sum(histogram[self._pixel_diff_margin + 1:])
            max_diff_value = max(filter(
                    lambda x: histogram[x], xrange(len(histogram))))
            if num_wrong_pixels > 0:
                logging.debug('Histogram of difference: %r', histogram)
                prefix_str = '%s-%dx%d' % ((time_str,) + images[0].size)
                message = ('Result of %s: total %d wrong pixels '
                           '(diff up to %d)' % (
                           prefix_str, num_wrong_pixels, max_diff_value))
                if num_wrong_pixels > max_acceptable_wrong_pixels:
                    logging.error(message)
                    return message

                message += (', within the acceptable range %d' %
                            max_acceptable_wrong_pixels)
                logging.warning(message)
            else:
                logging.info('Result: all pixels match (within +/- %d)',
                             max_diff_value)
            message = None
            return None
        finally:
            if message is not None:
                for i in (0, 1):
                    # Use time and image size as the filename prefix.
                    prefix_str = '%s-%dx%d' % ((time_str,) + images[i].size)
                    # TODO(waihong): Save to a better lossless format.
                    file_path = os.path.join(
                            self._output_dir,
                            '%s-%s.png' % (prefix_str, tags[i]))
                    logging.info('Output the image %d to %s', i, file_path)
                    images[i].save(file_path)

                file_path = os.path.join(
                        self._output_dir, '%s-diff.png' % prefix_str)
                logging.info('Output the diff image to %s', file_path)
                diff_image = ImageChops.difference(*images)
                gray_image = diff_image.convert('L')
                bw_image = gray_image.point(
                        lambda x: 0 if x <= self._pixel_diff_margin else 255,
                        '1')
                bw_image.save(file_path)
