#!/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, division, absolute_import

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

from subset_test_suite import SubsetTestSuite

# https://stackoverflow.com/a/377028
def which(program):
	def is_exe(fpath):
		return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

	fpath, _ = os.path.split(program)
	if fpath:
		if is_exe(program):
			return program
	else:
		for path in os.environ["PATH"].split(os.pathsep):
			exe_file = os.path.join(path, program)
			if is_exe(exe_file):
				return exe_file

	return None

fonttools = which ("fonttools")
ots_sanitize = which ("ots-sanitize")

if not fonttools:
	print("fonttools is not present, skipping test.")
	sys.exit (77)

def cmd(command):
	p = subprocess.Popen (
		command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	(stdoutdata, stderrdata) = p.communicate ()
	print (stderrdata, end="") # file=sys.stderr
	return stdoutdata, 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' + test.get_font_extension ())
	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))

	print ("stripping checksums.")
	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):
	print ("fonttools ttx %s" % file)
	return cmd([fonttools, "ttx", "-q", "-o-", file])

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

def has_ots ():
	if not ots_sanitize:
		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)

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.")
