# -*- coding: utf-8 -*-
import sys

"""
Reference:
https://doc.qt.io/squish/how-to-modify-squish-functions.html
https://doc.qt.io/squish/waitforimage-function.html#waitforimage-function
https://doc.qt.io/squish/rgs-testsettings.html
https://doc.qt.io/squish/test-suite-settings-view.html#test-settings
"""


def _ImageSearch(functionName, imageFile, parameterMap, searchRegion):
    """
    https://doc.qt.io/squish/test-suite-settings-view.html#image-search
    https://doc.qt.io/squish/rgs-testsettings.html
    """
    
    p = dict(parameterMap or {})
    
    # Get the value from the dictionary or fall back the default one
    occurrence = p.get("occurrence", 1)
    interval = p.get("interval", 1000)
    timeout = p.get("timeout", 20000)
    tolerant = p.get("tolerant", testSettings.imageSearchTolerant)
    threshold = p.get("threshold", testSettings.imageSearchThreshold)
    multiscale = p.get("multiscale", testSettings.imageSearchMultiscale)
    minScale = p.get("minScale", testSettings.imageSearchMinScale)
    maxScale = p.get("maxScale", testSettings.imageSearchMaxScale)
    
    
    def line(key,value,ignored):
        # This function is to combine the printed out text
        # But the logic needs to be discussed again. Also, one parameter per line needs to be confirmed
        text = "%s=%s" % (key,value)
        
        if key == "threshold" and ignored:
            text += " (Ignored: tolerant is set to false, threshold default not used)"
            
        if (key == "minScale" or key == "maxScale") and ignored:
            text += " (Ignored: either the tolerant or the multiscale are set to false, minScale and maxScale default not used)"
        
        return text
    
    params = [
        ("occurrence", occurrence, False),
        ("interval", interval, False),
        ("timeout", timeout, False),
        ("tolerant", tolerant, False),
        ("threshold", threshold, not tolerant),
        ("multiscale", multiscale, not tolerant),
        ("minScale", minScale, (not tolerant or not multiscale)),
        ("maxScale", maxScale, (not tolerant or not multiscale)),
        ("searchRegion", searchRegion, False),
    ]
    
    test.startSection("parameters for %s(%r)" % (functionName, imageFile))
    for key, value, ignored in params:
        test.log(
            line(key, value, ignored)
        )
    test.endSection()


def addLoggingToImageLookupFunctions(functionName):
    
    def decorator(orignalImageLookupFunction):
          
        def wrappedFunction(imageFile, parameterMap=None, searchRegion=None):
            # Log all parameters
            _ImageSearch(functionName, imageFile, parameterMap, searchRegion)
                     
            try: 
                # Invoke the original waitForImage to do the lookup
                if searchRegion is not None:
                    ImageRect = orignalImageLookupFunction(imageFile, parameterMap or {}, searchRegion)
                else:
                    ImageRect = orignalImageLookupFunction(imageFile, parameterMap or {})
            except LookupError:
                # Lookup failed -- no ScreenRectangle exists
                test.log("%s(%r) did not find a match" % (functionName, imageFile),)
                raise  # preserve normal Squish pass/fail behavior
            
            # On successful lookup, log the rectangle’s x/y/width/height properties    
            test.log(
                    "%s(%r) found a match" % (functionName, imageFile),
                    "x=%d, y=%d, width=%d, height=%d"
                    % (ImageRect.x, ImageRect.y, ImageRect.width, ImageRect.height),
                    )        
            
            
            # Highlight the image
            default_timeout = 3000       
            highlightObject(ImageRect, default_timeout, False)
            snooze(1) # To make the highlighting shows in the screenshot, pause script execution for 1s
            
            # Take a desktop screenshot and attach it to the report
            try:
                #matchedRegion = grabDesktopScreenshot().copy(ImageRect.x, ImageRect.y, ImageRect.width, ImageRect.height)
                desktop = grabDesktopScreenshot()
                test.attachImage(desktop, 
                                 "Matched region for %s. The screenshot was taken shortly before the click, rather than at the exact moment of the click." % imageFile)
               
            except RuntimeError:
                test.warning("Could not attach the screenshot")
                raise
            
            return ImageRect
        
        return wrappedFunction 
    
    return decorator

 
def wrapSquishFunction(functionName, wrappedFunctionGetter):
    # Standard Squish helper function for replacing a built-in function with a wrapped version, while keeping access to the original 
    module = sys.modules["squish"]
    if functionName in dir(module):
        # Keep the original function as functionName_original
        original = getattr(module, functionName)
        setattr(module, functionName + "_original", original)
        globals()[functionName + "_original"] = original 
        
        wrappedFunction = wrappedFunctionGetter(getattr(module, functionName))
        setattr(module, functionName, wrappedFunction)
    else:
        raise RuntimeError("function %s not part of squish module" % functionName)
 
    if functionName in globals():
        globals()[functionName] = wrappedFunction
        
wrapSquishFunction("waitForImage", addLoggingToImageLookupFunctions("waitForImage"))
wrapSquishFunction("findImage", addLoggingToImageLookupFunctions("findImage"))