#!/usr/bin/env python3

import sys, os, subprocess, hashlib

print("TAP version 14")

args = sys.argv[1:]

verbose = False
if args and args[0] == "-v":
    verbose = True
    args = args[1:]

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

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

EXE_WRAPPER = os.environ.get("MESON_EXE_WRAPPER")


def open_shape_batch_process():
    cmd = [hb_shape, "--batch"]
    if EXE_WRAPPER:
        cmd = [EXE_WRAPPER] + cmd

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


shape_process = open_shape_batch_process()
no_glyph_names_process = None


def shape_cmd(command, shape_process, verbose=False):
    global hb_shape

    # (Re)start shaper if it is dead
    if shape_process[0].poll() is not None:
        shape_process[0].stdin.close()
        shape_process[0].stdout.close()
        shape_process[0].stderr.close()
        shape_process[0] = open_shape_batch_process()[0]

    if verbose:
        print("# " + hb_shape + " " + " ".join(command))
    shape_process[0].stdin.write((";".join(command) + "\n").encode("utf-8"))
    shape_process[0].stdin.flush()
    return shape_process[0].stdout.readline().decode("utf-8").strip()


def plural(what):
    if not what.endswith("s"):
        what += "s"
    return what


def whats_var_name(what):
    return plural(what).replace("-", "_")


def supported_whats_var_name(what):
    whats = whats_var_name(what)
    return "supported_" + whats


def supported_whats(what):
    return globals()[supported_whats_var_name(what)]


def all_whats_var_name(what):
    whats = whats_var_name(what)
    return "all_" + whats


def all_whats(what):
    return globals()[all_whats_var_name(what)]


# Collect supported backends
for what in ["shaper", "face-loader", "font-funcs"]:
    subcommand = "--list-" + plural(what)

    cmd = [hb_shape, subcommand]
    if EXE_WRAPPER:
        cmd = [EXE_WRAPPER] + cmd

    what_process = subprocess.Popen(
        cmd,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=sys.stdout,
        env=env,
    )
    # Capture the output
    what_list = what_process.communicate()[0].decode("utf-8").strip().split()
    if what_process.returncode:
        sys.exit(f"Failed to run: {hb_shape} {subcommand}")
    whats = plural(what)
    var_name = supported_whats_var_name(what)
    globals()[var_name] = what_list
    print(f"# Supported {whats}: {what_list}")

# If running under Wine and not native dlls, make the respective shapers unavailable.
if os.environ.get("WINEPATH"):
    overrides = os.environ.get("WINEDLLOVERRIDES", "").lower()
    if "directwrite" in supported_shapers and overrides.find("dwrite") == -1:
        supported_shapers.remove("directwrite")
        print("# Skipping DirectWrite shaper under Wine.")
    if "uniscribe" in supported_shapers and overrides.find("usp10") == -1:
        supported_shapers.remove("uniscribe")
        print("# Skipping Uniscribe shaper under Wine.")


number = 0
passes = 0
fails = 0
skips = 0

if not len(args):
    args = ["-"]

for filename in args:
    if filename == "-":
        print("# Running tests from standard input")
    else:
        print("# Running tests in " + filename)

    if filename == "-":
        f = sys.stdin
    else:
        f = open(filename, encoding="utf8")

    # By default test all backends
    for what in ["shaper", "face-loader", "font-funcs"]:
        all_var_name = all_whats_var_name(what)
        globals()[all_var_name] = supported_whats(what)
    all_face_loaders = os.environ.get("HB_FACE_LOADER", "ot").split(",")
    all_shapers = os.environ.get("HB_SHAPER_LIST", "ot").split(",")

    # Right now we only test the 'ot' shaper if nothing specified,
    # but try all font-funcs unless overriden.
    # Only 'ot' face-loader is tested.

    for line in f:
        comment = False
        if line.startswith("#"):
            comment = True
            line = line[1:]

            if line.startswith(" "):
                if verbose:
                    print("#%s" % line)
                continue

        line = line.strip()
        if not line:
            continue

        if line.startswith("@"):
            # Directive
            line = line.strip()
            line = line.split("#")[0].strip()[1:]
            consumed = False
            for what in ["shaper", "face-loader", "font-funcs"]:
                whats = plural(what)
                if line.startswith(what) or line.startswith(whats):
                    command, values = line.split("=")
                    values = values.strip().split(",")

                    supported = supported_whats(what)
                    if command[-1] == "-":
                        # Exclude
                        values = [v for v in supported if v not in values]
                    else:
                        # Specify
                        values = [v for v in values if v in supported]

                    var_name = all_whats_var_name(what)
                    print(f"# Setting {whats} to test to {values}")
                    globals()[var_name] = values
                    consumed = True
            if consumed:
                print("#", line)
                continue
            else:
                print("Unrecognized directive: %s" % line, file=sys.stderr)
                sys.exit(1)

        fontfile, options, unicodes, glyphs_expected = line.split(";")
        options = options.split()
        if fontfile.startswith("/") or fontfile.startswith('"/'):
            if os.name == "nt":  # Skip on Windows
                continue

            fontfile, expected_hash = (fontfile.split("@") + [""])[:2]

            try:
                with open(fontfile, "rb") as ff:
                    if expected_hash:
                        actual_hash = hashlib.sha1(ff.read()).hexdigest().strip()
                        if actual_hash != expected_hash:
                            skips += 1
                            print(
                                "# Different version of %s found; Expected hash %s, got %s; skipping."
                                % (fontfile, expected_hash, actual_hash)
                            )
                            continue
            except IOError:
                skips += 1
                print("# %s not found, skip." % fontfile)
                continue
        else:
            cwd = os.path.dirname(filename)
            fontfile = os.path.normpath(os.path.join(cwd, fontfile))

        if comment:
            if verbose:
                print('# # %s "%s" --unicodes %s' % (hb_shape, fontfile, unicodes))
            continue

        skip_test = False
        shaper = None
        face_loader = None
        font_funcs = None
        new_options = []
        it = iter(options)
        for option in it:
            consumed = False
            for what in ["shaper", "face-loader", "font-funcs"]:
                if option.startswith("--" + what):
                    try:
                        backend = option.split("=")[1]
                    except IndexError:
                        backend = next(it)
                    if backend not in supported_whats(what):
                        skips += 1
                        number += 1
                        print(
                            f"ok {number} - {fontfile} # skip {what}={backend} not supported"
                        )
                        print(f"# Skipping test with {what}={backend}.")
                        skip_test = True
                        break
                    what = what.replace("-", "_")
                    globals()[what] = backend
                    consumed = True
            if not consumed:
                new_options.append(option)

            if skip_test:
                break
        if skip_test:
            continue
        options = new_options

        for face_loader in [face_loader] if face_loader else all_whats("face-loader"):
            for shaper in [shaper] if shaper else all_whats("shaper"):
                all_font_funcs_for_shaper = (
                    all_whats("font-funcs") if shaper == "ot" else [None]
                )
                for font_funcs in (
                    [font_funcs] if font_funcs else all_font_funcs_for_shaper
                ):
                    number += 1
                    extra_options = []

                    if shaper:
                        extra_options.append("--shaper=" + shaper)
                    if face_loader:
                        extra_options.append("--face-loader=" + face_loader)
                    if font_funcs:
                        extra_options.append("--font-funcs=" + font_funcs)

                    if glyphs_expected != "*":
                        extra_options.append("--verify")
                        extra_options.append("--unsafe-to-concat")
                        extra_options.append("--safe-to-insert-tatweel")

                    if verbose:
                        print(
                            "# shaper=%s face-loader=%s font-funcs=%s"
                            % (shaper, face_loader, font_funcs)
                        )
                    cmd = (
                        [fontfile] + ["--unicodes", unicodes] + options + extra_options
                    )
                    glyphs = shape_cmd(cmd, shape_process, verbose).strip()

                    if glyphs_expected == "*":
                        passes += 1
                        print(f"ok {number} - {fontfile}")
                        continue

                    final_glyphs = glyphs
                    final_glyphs_expected = glyphs_expected

                    if glyphs != glyphs_expected and glyphs.find("gid") != -1:
                        if not no_glyph_names_process:
                            no_glyph_names_process = open_shape_batch_process()

                        cmd2 = [fontfile] + ["--glyphs", "--no-glyph-names", glyphs]
                        final_glyphs = shape_cmd(cmd2, no_glyph_names_process).strip()

                        cmd2 = [fontfile] + [
                            "--glyphs",
                            "--no-glyph-names",
                            glyphs_expected,
                        ]
                        final_glyphs_expected = shape_cmd(
                            cmd2, no_glyph_names_process
                        ).strip()

                    # If the removal of glyph_ids failed, fail the test.
                    # https://github.com/harfbuzz/harfbuzz/issues/5169
                    if (
                        not final_glyphs_expected
                        or final_glyphs != final_glyphs_expected
                    ):
                        fails += 1
                        cmd = hb_shape + " " + " ".join(cmd)
                        print(f"not ok {number} - {cmd}")
                        print("   ---", file=sys.stderr)
                        print('   test_file: "' + filename + '"', file=sys.stderr)
                        print('   cmd: "' + cmd + '"', file=sys.stderr)
                        print('   actual:   "' + glyphs + '"', file=sys.stderr)
                        print('   expected: "' + glyphs_expected + '"', file=sys.stderr)
                        if final_glyphs != glyphs:
                            print(
                                '   actual_gids:   "' + final_glyphs + '"',
                                file=sys.stderr,
                            )
                            print(
                                '   expected_gids: "' + final_glyphs_expected + '"',
                                file=sys.stderr,
                            )
                        print("   ...", file=sys.stderr)
                    else:
                        cmd = hb_shape + " " + " ".join(cmd)
                        passes += 1
                        print(f"ok {number} - {cmd}")

print("# %d tests passed; %d failed; %d skipped." % (passes, fails, skips))
if not (fails + passes):
    print("# No tests ran.")
elif not (fails + skips):
    print("# All tests passed.")

print("1..%d" % number)
