import os
import platform
import shutil
import sys
import unittest

from os import path

topdir = 'examples'
outdir = 'test_output'
masters = None

def image_diff(file0,file1,output):
    '''
    return None if images are same
    return message if images are different
    produces diff image file in output
    '''
    if not hasattr(image_diff,'pixel_threshold'):
        image_diff.pixel_threshold = 30
        image_diff.percent_threshold = 2
    ret = None
    image0 = Image.open(file0)
    image1 = Image.open(file1)
    idiff = ImageChops.difference(*[i.convert('RGB') for i in [image0,image1]])
    bbox = idiff.getbbox()
    if bbox:
        pixels_diff = sum(sum(x) != 0 for x in idiff.crop(bbox).getdata())
        npixels = image0.size[0] * image0.size[1]
        if (pixels_diff >= image_diff.pixel_threshold) \
        or (pixels_diff >= (0.01 * image_diff.percent_threshold * npixels)):
            ImageChops.invert(idiff).save(output+'.png', format="PNG")
            ret = pixels_diff
    return ret

def run_example(testcase, args, outfiles=None):
    if outfiles is not None:
        for f in filter(path.exists, outfiles):
            os.remove(f)

    if isinstance(args, str):
        args = [args]

    opts = dict(shell = True,
                executable = None if platform.system() == 'Windows' \
                             else os.environ.get('SHELL','/bin/bash'),
                env = os.environ,
                stdout = PIPE,
                stderr = PIPE)
    cmd = '{exe} {script} {args}'.format(
        exe = sys.executable,
        script = path.join(topdir,args[0]),
        args = ' '.join(args[1:]))
    proc = Popen(cmd, **opts)
    out,err = proc.communicate()
    testcase.assertEqual(proc.returncode, 0, err.decode())
    if outfiles:
        for f in outfiles:
            errmsg = 'missing output file: '+f+'\ncommand: '+cmd
            testcase.assertTrue(path.exists(f),errmsg)
    return out.decode(),err.decode()

from .test_examples import *

def main():
    import argparse
    import os
    import random
    import sys
    import unittest

    from argparse import ArgumentParser, SUPPRESS, ArgumentDefaultsHelpFormatter

    import test

    global topdir, outdir, masters

    parser = ArgumentParser(usage=SUPPRESS,
        formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument('-d', '--topdir',
        default=topdir,
        help='''directory containing the examples''')
    parser.add_argument('-o', '--outdir',
        default=outdir,
        help='''output directory for files generated by examples''')
    parser.add_argument('-m', '--masters',
        default=masters,
        help='''directory containing masters with which to compare output''')

    def print_help():
        parser._print_help()
        unittest.main()
    parser._print_help = parser.print_help
    parser.print_help = print_help

    args,unknown_args = parser.parse_known_args(sys.argv)

    topdir = args.topdir
    outpdir = args.outdir
    masters = args.masters

    if not path.exists(outdir):
        os.makedirs(outdir)

    unittest.main(argv=unknown_args)
