# Copyright 2015 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 errno
from PIL import Image
import logging
import subprocess
import tempfile

from autotest_lib.client.cros.image_comparison import comparison_result
from autotest_lib.client.cros.video import method_logger


class PdiffImageComparer(object):
    """
    Compares two images using ChromeOS' perceptualdiff binary.

    """

    @method_logger.log
    def compare(self, golden_img_path, test_img_path, box=None):
        """
        Compares a test image against the specified golden image using the
        terminal tool 'perceptualdiff'.

        @param golden_img_path: path, complete path to a golden image.
        @param test_img_path: path, complete path to a test image.
        @param box: int tuple, left, upper, right, lower pixel coordinates.
                    Defines the rectangular boundary within which to compare.
        @return: int, number of pixels that are different.
        @raise : Whatever _pdiff_compare raises.

        """
        if not box:
            return self._pdiff_compare(golden_img_path, test_img_path)

        ext = '.png'
        tmp_golden_img_file = tempfile.NamedTemporaryFile(suffix=ext)
        tmp_test_img_file = tempfile.NamedTemporaryFile(suffix=ext)

        with tmp_golden_img_file, tmp_test_img_file:
            tmp_golden_img_path = tmp_golden_img_file.name
            tmp_test_img_path = tmp_test_img_file.name

            Image.open(golden_img_path).crop(box).save(tmp_golden_img_path)
            Image.open(test_img_path).crop(box).save(tmp_test_img_path)

            return self._pdiff_compare(tmp_golden_img_path, tmp_test_img_path)


    def _pdiff_compare(self, golden_img_path, test_img_path):
        """
        Invokes perceptualdiff using subprocess tools.

        @param golden_img_path: path, complete path to a golden image.
        @param test_img_path: path, complete path to a test image.
        @return: int, number of pixels that are different.
        @raise ValueError if image dimensions are not the same.
        @raise OSError: if file does not exist or can not be opened.

        """

        # TODO mussa: Could downsampling the images be good for us?

        tmp_diff_file = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
        args = ['perceptualdiff', golden_img_path, test_img_path, '-output',
                tmp_diff_file.name]

        logging.debug("Start process with args : " + str(args))

        p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        output = p.communicate()
        logging.debug('output of perceptual diff command is')
        logging.debug(output)

        stdoutdata = output[0]

        mismatch_error = "Image dimensions do not match"
        diff_message = "Images are visibly different"
        filenotfound_message = "Cannot open"

        #TODO(dhaddock): Check for image not created
        if p.returncode == 0:
            # pdiff exited with 0, images were the same
            return comparison_result.ComparisonResult(0, '', None)

        if mismatch_error in stdoutdata:
            raise ValueError("pdiff says: " + stdoutdata)

        if diff_message in stdoutdata:
            diff_pixels = [int(s) for s in stdoutdata.split() if s.isdigit()][0]
            return comparison_result.ComparisonResult(int(diff_pixels), '',
                                                      tmp_diff_file.name)

        if filenotfound_message in stdoutdata:
            raise OSError(errno.ENOENT, "pdiff says: " + stdoutdata)

        raise RuntimeError("Unknown result from pdiff: "
                           "Output : " + stdoutdata)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass