#!/usr/bin/env python3

# Copyright (C) 2019 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import sys
import optparse
from webkitpy.common.host import Host
from webkitpy.port.base import Port

import logging
from webkitpy.common.system.logutils import configure_logging

_log = logging.getLogger(os.path.basename(__file__))
configure_logging(logging.INFO)

option_parser = optparse.OptionParser(usage='usage: %prog [options] [imageA] [imageB]')
option_parser.add_option('--tolerance', action='store', dest='tolerance',
                         help='Tolerance percent. Defaults to 0.1')
option_parser.add_option('--platform', action='store',
                         help='Platform to use (e.g., "gtk")')
option_parser.add_option('--gtk', action='store_const', dest='platform', const='gtk',
                         help='Alias for --platform=gtk')
option_parser.add_option('--wpe', action='store_const', dest='platform', const='wpe',
                         help='Alias for --platform=wpe')
option_parser.add_option('--release', action='store_const', const='Release', dest="configuration",
                         help='Set the configuration to Release')
option_parser.add_option('--debug', action='store_const', const='Debug', dest="configuration",
                        help='Set the configuration to Release')
option_parser.add_option('--writediff', action='store', dest="destfile",
                        help='Write the resulting image diff to DESTFILE')

options, args = option_parser.parse_args()

if len(args) < 2:
    _log.error("Incorrect number of arguments. At least the path to two images is needed")
    sys.exit(1)

with open(args[0], mode='rb') as file:
    imageContentA = file.read()
with open(args[1], mode='rb') as file:
    imageContentB = file.read()

try:
    port = Host().port_factory.get(options.platform, options)
except NotImplementedError as e:
    _log.error(str(e))
    sys.exit(1)

image_diff, diff_percent, error = port.diff_image(imageContentA, imageContentB, options.tolerance)

if error is not None:
    _log.error("ImageDiff returned the following error: %s" % error)
    sys.exit(1)

_log.info("The tolerance used is: %s" % options.tolerance)
_log.info("The diff between the two images is: %s" % diff_percent)

if options.destfile:
    if image_diff is not None:
        with open(options.destfile, mode='wb') as file:
            file.write(image_diff)
        _log.info("Wrote diff image to %s" % options.destfile)
    else:
        _log.warning("Not writing empty diff image")
