# Lint as: python2, python3
# 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."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import logging
import os
import time

from PIL import ImageChops
from six.moves import range


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([x for x in range(len(histogram)) if histogram[x]])
            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)
