#!/usr/bin/env python3

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

print("TAP version 14")

args = sys.argv[1:]
if (
    not args
    or not os.path.exists(args[0])
    or "hb-vector" not in args[0]
):
    sys.exit("First argument does not seem to point to usable hb-vector.")
hb_vector, args = args[0], args[1:]

if not args:
    args = ["-"]

env = os.environ.copy()
env["LC_ALL"] = "C"
EXE_WRAPPER = os.environ.get("MESON_EXE_WRAPPER")


def resolve_path(base, path):
    if os.path.isabs(path):
        return path
    return os.path.normpath(os.path.join(base, path))


def open_vector_batch_process():
    cmd = [hb_vector, "--batch"]
    if EXE_WRAPPER:
        cmd = [EXE_WRAPPER] + cmd

    process = subprocess.Popen(
        cmd,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        env=env,
        text=True,
    )
    return [process]


def close_vector_batch_process(vector_process):
    process = vector_process[0]
    if process is None:
        return

    if process.stdin:
        process.stdin.close()
    if process.stdout:
        process.stdout.close()

    process.wait()
    vector_process[0] = None


vector_process = open_vector_batch_process()


def build_vector_command(font_path, options, unicodes, output_path):
    command = []
    if options:
        command.extend(shlex.split(options))
    command.extend([f"--output-file={output_path}", f"--unicodes={unicodes}", font_path])
    return command


def run_vector_single(command):
    cmd = [hb_vector]
    cmd.extend(command)
    if EXE_WRAPPER:
        cmd = [EXE_WRAPPER] + cmd
    return subprocess.run(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)


def vector_cmd(command, vector_process):
    process = vector_process[0]

    # (Re)start vector tool if it is dead.
    if process.poll() is not None:
        if process.stdin:
            process.stdin.close()
        if process.stdout:
            process.stdout.close()
        vector_process[0] = open_vector_batch_process()[0]
        process = vector_process[0]

    process.stdin.write(";".join(command) + "\n")
    process.stdin.flush()

    diagnostics = []
    while True:
        line = process.stdout.readline()
        if line == "":
            return None, diagnostics

        line = line.rstrip("\n")
        if line in ("success", "failure"):
            return line, diagnostics

        diagnostics.append(line)


def run_vector(font_path, options, unicodes, output_path):
    command = build_vector_command(font_path, options, unicodes, output_path)
    status, diagnostics = vector_cmd(command, vector_process)

    if status == "success":
        return subprocess.CompletedProcess(
            args=command,
            returncode=0,
            stdout="",
            stderr="\n".join(diagnostics),
        )

    # Fall back to one-shot execution for proper diagnostics.
    result = run_vector_single(command)
    if diagnostics:
        stderr = "\n".join(diagnostics)
        if result.stderr:
            stderr += "\n" + result.stderr
        result = subprocess.CompletedProcess(
            args=result.args,
            returncode=result.returncode,
            stdout=result.stdout,
            stderr=stderr,
        )
    return result


def parse_unicodes(s):
    # Match test/shape/hb_test_tools.py Unicode.parse semantics.
    s = re.sub(r"0[xX]", " ", s)
    s = re.sub(r"[<+\->{},;&#\\xXuUnNiI\n\t]", " ", s)
    try:
        return "".join(chr(int(x, 16)) for x in s.split())
    except ValueError as e:
        raise ValueError(f"invalid unicode codepoint list: {s!r}") from e


number = 0
fails = 0

try:
    for filename in args:
        if filename == "-":
            f = sys.stdin
            base = os.getcwd()
            print("# Running tests from standard input")
        else:
            f = open(filename, encoding="utf-8")
            base = os.path.dirname(os.path.abspath(filename))
            print("# Running tests in " + filename)

        for lineno, line in enumerate(f, start=1):
            line = line.strip()
            if not line or line.startswith("#"):
                continue

            number += 1
            fields = line.split(";", 3)
            if len(fields) != 4:
                fails += 1
                print(f"not ok {number} - parse:{filename}:{lineno}")
                print("# malformed test line, expected 4 ';'-separated fields")
                continue

            font_file, options, unicodes, expected_file = fields
            name = expected_file
            font_path = resolve_path(base, font_file)
            expected_path = resolve_path(base, expected_file)

            if not os.path.exists(font_path):
                fails += 1
                print(f"not ok {number} - {name}")
                print(f"# font file not found: {font_path}")
                continue

            if not os.path.exists(expected_path):
                fails += 1
                print(f"not ok {number} - {name}")
                print(f"# expected output file not found: {expected_path}")
                continue

            try:
                parse_unicodes(unicodes)
            except ValueError as e:
                fails += 1
                print(f"not ok {number} - {name}")
                print("# " + str(e))
                continue

            with tempfile.NamedTemporaryFile(prefix="hb-vector-test-", suffix=".svg", delete=False) as tmp:
                output_path = tmp.name

            try:
                result = run_vector(font_path, options, unicodes, output_path)
                if result.returncode != 0:
                    fails += 1
                    print(f"not ok {number} - {name}")
                    print(f"# hb-vector exited with code {result.returncode}")
                    stderr = result.stderr.strip()
                    if stderr:
                        for l in stderr.splitlines():
                            print("# " + l)
                    continue

                if not os.path.exists(output_path):
                    fails += 1
                    print(f"not ok {number} - {name}")
                    print("# hb-vector did not create output file")
                    continue

                with open(expected_path, encoding="utf-8") as fp:
                    expected = fp.read()
                with open(output_path, encoding="utf-8") as fp:
                    actual = fp.read()

                if actual == expected:
                    print(f"ok {number} - {name}")
                    continue

                fails += 1
                print(f"not ok {number} - {name}")
                diff = unified_diff(
                    expected.splitlines(keepends=True),
                    actual.splitlines(keepends=True),
                    fromfile=expected_path,
                    tofile="actual",
                )
                for diff_line in diff:
                    print("# " + diff_line.rstrip("\n"))
            finally:
                if os.path.exists(output_path):
                    os.unlink(output_path)

        if f is not sys.stdin:
            f.close()
finally:
    close_vector_batch_process(vector_process)

print(f"1..{number}")

if fails:
    sys.exit(1)
