#!/usr/bin/env python

# Runs a subsetting test suite. Compares the results of subsetting via harfbuz
# to subsetting via fonttools.

from __future__ import print_function

import io
from difflib import unified_diff
import os
import re
import subprocess
import sys
import tempfile

from subset_test_suite import SubsetTestSuite


def cmd(command):
	p = subprocess.Popen (
		command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	p.wait ()
	print (p.stderr.read (), end="") # file=sys.stderr
	return p.stdout.read (), p.returncode

def read_binary(file_path):
	with open(file_path, 'rb') as f:
		return f.read()

def fail_test(test, cli_args, message):
	print ('ERROR: %s' % message)
	print ('Test State:')
	print ('  test.font_path    %s' % os.path.abspath(test.font_path))
	print ('  test.profile_path %s' % os.path.abspath(test.profile_path))
	print ('  test.unicodes	    %s' % test.unicodes())
	expected_file = os.path.join(test_suite.get_output_directory(),
				     test.get_font_name())
	print ('  expected_file	    %s' % os.path.abspath(expected_file))
	return 1

def run_test(test, should_check_ots):
	out_file = os.path.join(tempfile.mkdtemp(), test.get_font_name() + '-subset.ttf')
	cli_args = [hb_subset,
		    "--font-file=" + test.font_path,
		    "--output-file=" + out_file,
		    "--unicodes=%s" % test.unicodes()]
	cli_args.extend (test.get_profile_flags())
	print (' '.join(cli_args))
	_, return_code = cmd(cli_args)

	if return_code:
		return fail_test(test, cli_args, "%s returned %d" % (' '.join(cli_args), return_code))

	expected_ttx, return_code = run_ttx(os.path.join(test_suite.get_output_directory(),
					    test.get_font_name()))
	if return_code:
		return fail_test(test, cli_args, "ttx (expected) returned %d" % (return_code))

	actual_ttx, return_code = run_ttx(out_file)
	if return_code:
		return fail_test(test, cli_args, "ttx (actual) returned %d" % (return_code))

	expected_ttx = strip_check_sum (expected_ttx)
	actual_ttx = strip_check_sum (actual_ttx)

	if not actual_ttx == expected_ttx:
		for line in unified_diff(expected_ttx.splitlines(1), actual_ttx.splitlines(1)):
			sys.stdout.write(line)
		sys.stdout.flush()
		return fail_test(test, cli_args, 'ttx for expected and actual does not match.')

	if should_check_ots:
		print ("Checking output with ots-sanitize.")
		if not check_ots(out_file):
			return fail_test(test, cli_args, 'ots for subsetted file fails.')

	return 0

def run_ttx(file):
	cli_args = ["ttx",
		    "-o-",
		    file]
	return cmd(cli_args)

def strip_check_sum (ttx_string):
	return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
		       'checkSumAdjustment value="0x00000000"',
		       ttx_string, count=1)

def has_ots():
	_, returncode = cmd(["which", "ots-sanitize"])
	if returncode:
		print("OTS is not present, skipping all ots checks.")
		return False
	return True

def check_ots (path):
	ots_report, returncode = cmd(["ots-sanitize", path])
	if returncode:
		print("OTS Failure: %s" % ots_report);
		return False
	return True

args = sys.argv[1:]
if not args or sys.argv[1].find('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
	print ("First argument does not seem to point to usable hb-subset.")
	sys.exit (1)
hb_subset, args = args[0], args[1:]

if not len(args):
	print ("No tests supplied.")
	sys.exit (1)

_, returncode = cmd(["which", "ttx"])
if returncode:
	print("TTX is not present, skipping test.")
	sys.exit (77)

has_ots = has_ots()

fails = 0
for path in args:
	with io.open(path, mode="r", encoding="utf-8") as f:
		print ("Running tests in " + path)
		test_suite = SubsetTestSuite(path, f.read())
		for test in test_suite.tests():
			fails += run_test(test, has_ots)

if fails != 0:
	print (str (fails) + " test(s) failed.")
	sys.exit(1)
else:
	print ("All tests passed.")
