#requires pip install python-opencv-headless

import argparse
import os
import sys

# We deliberately imread() files that may only exist on one side (missing
# candidate/golden), which OpenCV otherwise logs as a noisy "can't open/read
# file" WARN. diff_one() handles the resulting None explicitly and records a
# missing status, so quiet OpenCV to errors and above before it is imported.
os.environ.setdefault("OPENCV_LOG_LEVEL", "ERROR")

import cv2 as cv
import numpy as np

parser = argparse.ArgumentParser(description=
"""
Compares candidate images against goldens by pixels, writing one status line
per image and (optionally) two diff images per image.

A single process diffs multiple images in order to amortize the cost of spawning
the Python interpreter and importing OpenCV (cv2).

Two ways to feed images to a process:
  --names    diff a fixed list of file names, then exit.
  --serve    stay alive reading one file name per line from stdin, writing
             "done" to stdout after each, so the parent (diff.py) can pull work
             dynamically and keep every worker busy until the queue is empty.

output file {status}            one status line per image
output file {name}.diff0.png    the exact abs(A - B) of each pixel
output file {name}.diff1.png    a mask which has 255 for difference, 0 otherwise
""")

mode = parser.add_mutually_exclusive_group(required=True)
mode.add_argument("-N", "--names", type=str, nargs='+', help="space-separated image file names (e.g. foo.png bar.png) to diff; each is looked up by name in the --candidate and --golden directories")
mode.add_argument("--serve", action='store_true', help="read image file names from stdin, one per line, diffing each and writing 'done' to stdout after each; exit on EOF")
parser.add_argument("-c", "--candidate", type=str, required=True, help="candidate DIRECTORY of images to diff")
parser.add_argument("-g", "--golden", type=str, required=True, help="golden DIRECTORY to compare against")
parser.add_argument("-s", "--status", type=str, required=True, help="output stats file name and location")
parser.add_argument("-o", "--outdir", type=str, help="output directory to store image diffs, if not provided then no output image is saved")
parser.add_argument("-v", "--verbose", action='store_true', help="enable verbose logging")
parser.add_argument("-l", "--log", action='store_true', help="redirect all verbose logging to a per-image file")
parser.add_argument("-H", "--histogram", action='store_true', help="compare images using histograms as an additional method for ruling out 'same' images. This should prevent subtle differences in the image that should not be visible from preventing a passing result")

args = parser.parse_args()

def remove_suffix(name, oldsuffix):
    if name.endswith(oldsuffix):
        name = name[:-len(oldsuffix)]
    return name

# The landing page (index.html) embeds one small thumbnail per image so that
# opening it doesn't force the browser to download every full resolution golden,
# candidate and diff at once, which DOSes phones. The full resolution image is
# still a click away via the surrounding <a href>. Thumbnails are written next
# to the diff images in the output directory.
THUMBNAIL_HEIGHT = 192

def write_thumbnail(image, path):
    # Downscale to THUMBNAIL_HEIGHT keeping aspect ratio; never upscale a smaller
    # image. No-op when the source image failed to load.
    if image is None:
        return
    height, width = image.shape[:2]
    if height > THUMBNAIL_HEIGHT:
        scale = THUMBNAIL_HEIGHT / height
        new_size = (max(1, round(width * scale)), THUMBNAIL_HEIGHT)
        image = cv.resize(image, new_size, interpolation=cv.INTER_AREA)
    cv.imwrite(path, image)

def verbose_log(name, val):
    if not args.verbose:
        return
    if args.log:
        with open(f"tmp/{name}.log", "a") as log_file:
            log_file.write(val+"\n")
    else:
        print(val, file=sys.stderr)

def diff_one(filename, status):
    name = remove_suffix(filename, ".png")
    candidate_path = os.path.join(args.candidate, filename)
    golden_path = os.path.join(args.golden, filename)

    candidate = None
    golden = None
    diff = None
    rgb_diff = None
    mask = None
    total_diff_count = 0
    max_diff = 0
    avg = 0.0
    hist_result = 1.0
    size_match = False
    failed = False
    try:
        verbose_log(name, f"loading {candidate_path}")
        candidate = cv.imread(candidate_path)
        verbose_log(name, f"loading {golden_path}")
        golden = cv.imread(golden_path)

        if candidate is not None and golden is not None:
            size_match = candidate.shape == golden.shape
            # get absolute difference between golden and candidate
            diff = cv.absdiff(golden, candidate)
            #convert diff to grey scale to make calculations easier
            grey_diff = cv.cvtColor(diff, cv.COLOR_BGR2GRAY)
            #convert to rgb for output png
            rgb_diff = cv.cvtColor(diff, cv.COLOR_BGR2RGB)
            # convert the diff to just white where a difference is
            _, mask = cv.threshold(grey_diff, 0, 255, cv.THRESH_BINARY)
            # get the total number of different pixels
            total_diff_count = cv.countNonZero(grey_diff)
            # get the max channel independent difference
            max_diff = int(diff.max())
            # get average pixel diff, this result is slitely different then imageDiff but its very close.
            # the only difference is that we first convert the diff to grey scale rather than adding the max of every channel
            avg = grey_diff.sum() / (grey_diff.shape[0]*grey_diff.shape[1]*255)

            if args.histogram:
                # convert to HSV
                hsv_candidate = cv.cvtColor(candidate, cv.COLOR_BGR2HSV)
                hsv_golden = cv.cvtColor(golden, cv.COLOR_BGR2HSV)

                # down sample to 32x32 for the histogram
                h_bins = 32
                s_bins = 32
                histSize = [h_bins, s_bins]

                # available range for hue and saturation
                h_ranges = [0, 180]
                s_ranges = [0, 256]
                ranges = h_ranges + s_ranges

                # get our histograms
                hist_candidate = cv.calcHist(hsv_candidate, [0,1], None, histSize, ranges, accumulate=False)
                hist_golden = cv.calcHist(hsv_golden, [0,1], None, histSize, ranges, accumulate=False)

                # compare using CORREL histogram algorithm. the different options are detailed here
                # https://docs.opencv.org/3.4/d6/dc7/group__imgproc__hist.html#ga994f53817d621e2e4228fc646342d386
                # a hist_result of 1.0 means identical with this method. any variance results in a number less then 1.0
                hist_result = cv.compareHist(hist_candidate, hist_golden, cv.HISTCMP_CORREL)

    except Exception as E:
        print(f"Failed to load and process images {E}", file=sys.stderr)
        failed = True

    # Write the golden/candidate thumbnails here, before the early returns below,
    # so identical and missing entries get them too (they don't reach the diff
    # writing block at the end).
    if args.outdir:
        write_thumbnail(candidate, os.path.join(args.outdir, name + ".candidate.thumb.png"))
        write_thumbnail(golden, os.path.join(args.outdir, name + ".golden.thumb.png"))

    status.write(name + "\t")
    if failed:
        status.write("failed\n")
        verbose_log(name, "failed to load golden or candidate")
        return
    if candidate is None:
        status.write("missing_candidate\n")
        verbose_log(name, "missing candidate for " + name)
        return
    if golden is None:
        status.write("missing_golden\n")
        verbose_log(name, "missing golden for " + name)
        return
    if failed:
        status.write("failed\n")
        verbose_log(name, "failed to load golden or candidate")
        return
    if total_diff_count == 0:
        status.write("identical\n")
        verbose_log(name, "files are identical")
        return
    if not size_match:
        status.write("sizemismatch\n")
        verbose_log(name, "files are not the same size")
        return
    status.write(str(max_diff)+"\t")
    # prevent python from writing out in scientific notation
    status.write(f"{float(avg):.5f}\t")
    status.write(str(total_diff_count)+"\t")
    status.write(str(diff.shape[0]*diff.shape[1]))
    # add our histogram result as the last value of the status file or write a new line to say we are finished with this status
    if args.histogram:
        status.write(f"\t{float(hist_result):.5f}\n")
    else:
        status.write("\n")

    # save the output files if location provided
    if args.outdir:
        # color diff file location
        c_diff_path = os.path.join(args.outdir, name + ".diff0.png")
        # mask diff file location
        c_mask_path = os.path.join(args.outdir, name + ".diff1.png")
        verbose_log(name, f"writing images {c_diff_path} and {c_mask_path}")
        cv.imwrite(c_diff_path, rgb_diff)
        cv.imwrite(c_mask_path, mask)
        write_thumbnail(rgb_diff, os.path.join(args.outdir, name + ".diff0.thumb.png"))
        write_thumbnail(mask, os.path.join(args.outdir, name + ".diff1.thumb.png"))
        verbose_log(name, "finished writing output images")

def prepare_dirs():
    if args.log:
        os.makedirs("tmp", exist_ok=True)

    # make path to stats file if necessary
    if os.path.dirname(args.status):
        os.makedirs(os.path.dirname(args.status), exist_ok=True)
    if args.outdir:
        os.makedirs(args.outdir, exist_ok=True)

def main():
    # A single process handles the whole list; open the status file once and
    # append one line per image.
    prepare_dirs()
    with open(args.status, "a") as status:
        for filename in args.names:
            diff_one(filename, status)

def serve():
    # Interactive worker: the parent (diff.py) keeps this process alive and
    # feeds it one image file name per line on stdin, so cv2 is imported once
    # and then reused across many images. After each image we append its status
    # line to the status file and write "done" to stdout so the parent knows
    # we're ready for the next name. Exit on EOF.
    prepare_dirs()
    with open(args.status, "a") as status:
        for line in sys.stdin:
            filename = line.strip()
            if not filename:
                continue
            diff_one(filename, status)
            status.flush()
            sys.stdout.write("done\n")
            sys.stdout.flush()

if __name__ == '__main__':
    if args.serve:
        serve()
    else:
        main()
