# Copyright (c) 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.

import ConfigParser
import logging

from autotest_lib.client.cros.image_comparison import bp_http_client
from autotest_lib.client.cros.image_comparison import bp_image_comparer
from autotest_lib.client.cros.image_comparison import pdiff_image_comparer
from autotest_lib.client.cros.image_comparison import publisher
from autotest_lib.client.cros.image_comparison import rgb_image_comparer
from autotest_lib.client.cros.image_comparison import upload_on_fail_comparer
from autotest_lib.client.cros.image_comparison import verifier
from autotest_lib.client.cros.video import method_logger


class ImageComparisonFactory(object):
    """
    Responsible for instantiating objects used in image comparison based tests.

    """


    def __init__(self, conf_filepath):
        """
        @param conf_filepath: path, full path to the conf file.

        """
        self.conf_filepath = conf_filepath
        self._load_configuration()


    def _load_configuration(self):
        """
        Loads values from configuration file.

        """

        parser = ConfigParser.SafeConfigParser()
        parser.read(self.conf_filepath)
        self.bp_base_projname = parser.get('biopic', 'project_name')
        self.bp_email = parser.get('biopic', 'contact_email')
        self.bp_wait_time = parser.getint('biopic',
                                          'wait_time_btwn_comparisons')
        self.bp_upload_retries = parser.getint('biopic', 'upload_retries')

        self.pixel_thres = parser.getint('rgb', 'rgb_pixel_threshold')

        self.pixel_count_thres = parser.getint('all', 'pixel_count_threshold')
        self.desired_comp_h = parser.getint('all', 'desired_comp_h')
        self.desired_comp_w = parser.getint('all', 'desired_comp_w')


    @method_logger.log
    def make_rgb_comparer(self):
        """
        @returns an RGBImageComparer object initialized with config. values.

        """
        return rgb_image_comparer.RGBImageComparer(self.pixel_thres)


    @method_logger.log
    def make_bp_comparer(self, project_name=None):
        """

        @param project_name: string, name of the project to use in bp.

        @returns a BpImageComparer object if it was successfully created, else
                 an RGBComparer object.

        """
        if not project_name:
            project_name = self.bp_base_projname
        return self._make_bp_comparer_helper(project_name)[0]


    @method_logger.log
    def make_pdiff_comparer(self):
        """
        @returns a PDiffImageComparer object.

        """
        return pdiff_image_comparer.PdiffImageComparer()


    @method_logger.log
    def make_upload_on_fail_comparer(self, project_name=None):
        """
        @param project_name: string, name of project to use in bp.

        @returns an UploadOnFailComparer object.

        """
        comparer, success = self._make_bp_comparer_helper(project_name)

        if success:
            # bp comparer was successfully made
            return upload_on_fail_comparer.UploadOnFailComparer(
                    local_comparer = self.make_pdiff_comparer(),
                    remote_comparer = comparer,
                    threshold = self.pixel_count_thres)

        # bp comparer was not made, we must have gotten rgb instead
        return comparer


    @method_logger.log
    def make_image_verifier(self, image_comparer, stop_on_first_failure=False):
        """
        @param image_comparer: any object that implements compare(). Currently,
                               it could BpImageComparer, RGBImageComparer or
                               UploadOnFailComparer.

        @param stop_on_first_failure: bool, True if we should stop the test when
                                      we encounter the first failed comparison.
                                      False if we should continue the test.
        @returns a Verifier object initialized with config. values.

        """
        if self.desired_comp_h == 0 or self.desired_comp_w == 0:
            box = None
        else:
            box = (0, 0, self.desired_comp_w, self.desired_comp_h)

        return verifier.Verifier(image_comparer,
                                 stop_on_first_failure,
                                 threshold=self.pixel_count_thres,
                                 box=box)


    def _make_bp_comparer_helper(self, project_name):
        """
        Internal helper method to make a BpImageComparer object.
        We use the try logic because sometime bp service is not availabe.In that
        case we should continue with the test and use a local comparer.

        @param project_name: string, name of project to use in bp.

        @returns a tuple containing (BpImageComparer object initialized with
                 config. values, True) if the initialization was successful.
                 Else (RGBImageComparer object, False).

        """
        success = False
        try:
            comparer = bp_image_comparer.BpImageComparer(project_name,
                                                         self.bp_email,
                                                         self.bp_wait_time,
                                                         self.bp_upload_retries)
            success = True
        except bp_http_client.BiopicClientError:
            logging.debug('**Could not make BpImageComparer. Defaulting to '
                          'Local Pdiff Comparer')
            # we don't expect other kinds of exceptions to occur. If they do
            # we will know about it and decide what to do
            comparer = self.make_pdiff_comparer()
        return comparer, success


    @method_logger.log
    def make_imagediff_publisher(self, results_folder):
        """
        @param results_folder: path, where to publish the results to
        @returns an ImageDIffPublisher object

        """
        return publisher.ImageDiffPublisher(results_folder)