#!/usr/bin/env python3

"""usage: ./gen-ucd-table [--rust] ucd.nounihan.grouped.xml [/path/to/hb-script-list.h]

Input file:
* https://unicode.org/Public/UCD/latest/ucdxml/ucd.nounihan.grouped.zip
"""

# https://github.com/harfbuzz/packtab
import packTab
import packTab.ucdxml

import sys, re
import logging

logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.INFO)

if len(sys.argv) > 1 and sys.argv[1] == "--rust":
    del sys.argv[1]
    logging.info("Generating Rust code...")
    language = "rust"
else:
    logging.info("Generating C code...")
    language = "c"
language = packTab.languages[language]

if len(sys.argv) not in (2, 3):
    sys.exit(__doc__)

logging.info("Loading UCDXML...")
ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1])
ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml)

hb_script_list_h = "hb-script-list.h" if len(sys.argv) < 3 else sys.argv[2]

logging.info("Preparing data tables...")


# This is how the data is encoded:
#
# General_Category (gc), Canonical_Combining_Class (ccc),
# and Script (sc) are encoded as integers.
#
# Mirroring character (bmg) is encoded as difference from
# the original character.
#
# Composition & Decomposition (dm) are encoded elaborately,
# as discussed below.

gc = [u["gc"] for u in ucd]
ccc = [int(u["ccc"]) for u in ucd]
bmg = [int(v, 16) - int(u) if v else 0 for u, v in enumerate(u["bmg"] for u in ucd)]
sc = [u["sc"] for u in ucd]


# Prepare Compose / Decompose data
#
# This code is very dense.  See hb_ucd_compose() / hb_ucd_decompose() for the logic.

dm = {
    i: tuple(int(v, 16) for v in u["dm"].split())
    for i, u in enumerate(ucd)
    if u["dm"] != "#" and u["dt"] == "can" and not (0xAC00 <= i < 0xAC00 + 11172)
}
ce = {i for i, u in enumerate(ucd) if u["Comp_Ex"] == "Y"}

assert not any(v for v in dm.values() if len(v) not in (1, 2))
dm1 = sorted(set(v for v in dm.values() if len(v) == 1))
assert all((v[0] >> 16) in (0, 2) for v in dm1)
dm1_p0_array = ["0x%04X" % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0]
dm1_p2_array = ["0x%04X" % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2]
dm1_order = {v: i + 1 for i, v in enumerate(dm1)}

dm2 = sorted(
    (v + (i if i not in ce and not ccc[i] else 0,), v)
    for i, v in dm.items()
    if len(v) == 2
)

filt = lambda v: (
    (v[0] & 0xFFFFF800) == 0x0000
    and (v[1] & 0xFFFFFF80) == 0x0300
    and (v[2] & 0xFFF0C000) == 0x0000
)
dm2_u32_array = [v for v in dm2 if filt(v[0])]
dm2_u64_array = [v for v in dm2 if not filt(v[0])]
assert dm2_u32_array + dm2_u64_array == dm2
dm2_u32_array = [
    "HB_CODEPOINT_ENCODE3_11_7_14 (0x%04X, 0x%04X, 0x%04X)" % v[0]
    for v in dm2_u32_array
]
dm2_u64_array = [
    "HB_CODEPOINT_ENCODE3 (0x%04X, 0x%04X, 0x%04X)" % v[0] for v in dm2_u64_array
]

l = 1 + len(dm1_p0_array) + len(dm1_p2_array)
dm2_order = {v[1]: i + l for i, v in enumerate(dm2)}

dm_order = {None: 0}
dm_order.update(dm1_order)
dm_order.update(dm2_order)


# Prepare General_Category / Script mapping arrays

gc_order = dict()
for i, v in enumerate(
    (
        "Cc",
        "Cf",
        "Cn",
        "Co",
        "Cs",
        "Ll",
        "Lm",
        "Lo",
        "Lt",
        "Lu",
        "Mc",
        "Me",
        "Mn",
        "Nd",
        "Nl",
        "No",
        "Pc",
        "Pd",
        "Pe",
        "Pf",
        "Pi",
        "Po",
        "Ps",
        "Sc",
        "Sk",
        "Sm",
        "So",
        "Zl",
        "Zp",
        "Zs",
    )
):
    gc_order[i] = v
    gc_order[v] = i

sc_order = dict()
sc_array = []
sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
for line in open(hb_script_list_h):
    m = sc_re.search(line)
    if not m:
        continue
    name = m.group(1)
    tag = "".join(m.group(i) for i in range(2, 6))
    i = len(sc_array)
    sc_order[tag] = i
    sc_order[i] = tag
    if language.name == "rust":
        name = name.replace("HB_SCRIPT_", "script::")
    sc_array.append(name)


# Write out main data

DEFAULT = "DEFAULT"
COMPACT = "COMPACT"
SLOPPY = "SLOPPY"

compression_level = {
    DEFAULT: 3,
    COMPACT: 9,
    SLOPPY: 9,
}

logging.info("Generating output...")
print("/* == Start of generated table == */")
print("/*")
print(" * The following table is generated by running:")
print(" *")
print(
    " *   ./gen-ucd-table.py %sucd.nounihan.grouped.xml hb-script-list.h"
    % (("--%s " % language.name) if language.name != "c" else "")
)
print(" *")
print(" * on file with this description:", ucdxml.description)
print(" */")
print()
if language.name == "c":
    print("#ifndef HB_UCD_TABLE_HH")
    print("#define HB_UCD_TABLE_HH")
    print()
    print('#include "hb.hh"')
    print()
elif language.name == "rust":
    print("pub(crate) mod ucd {")
    print()
    print("#![allow(unused_parens)]")
    print("#![allow(clippy::unnecessary_cast, clippy::unreadable_literal, clippy::double_parens)]")
    print()
    print("use crate::hb::algs::{HB_CODEPOINT_ENCODE3, HB_CODEPOINT_ENCODE3_11_7_14};")
    print("use crate::hb::common::script;")
    print("use crate::hb::common::Script as hb_script_t;")
    print()
else:
    assert False, "Unknown language: %s" % language.name

# Write mapping data

uint16_t = language.type_name("u16")
uint32_t = language.type_name("u32")
uint64_t = language.type_name("u64")

if language.name == "c":
    private = True
elif language.name == "rust":
    private = False
else:
    assert False, "Unknown language: %s" % language.name

code = packTab.Code("_hb_ucd")
sc_array, _ = code.addArray("hb_script_t", "sc_map", sc_array)
dm1_p0_array, _ = code.addArray(uint16_t, "dm1_p0_map", dm1_p0_array)
dm1_p2_array, _ = code.addArray(uint16_t, "dm1_p2_map", dm1_p2_array)
dm2_u32_array, _ = code.addArray(uint32_t, "dm2_u32_map", dm2_u32_array)
dm2_u64_array, _ = code.addArray(uint64_t, "dm2_u64_map", dm2_u64_array)
code.print_code(language=language, private=private)

datasets = [
    ("gc", gc, "Cn", gc_order),
    ("ccc", ccc, 0, None),
    ("bmg", bmg, 0, None),
    ("sc", sc, "Zzzz", sc_order),
    ("dm", dm, None, dm_order),
]


# Write main data

modes = {}
if language.name == "c":
    modes[DEFAULT] = "#ifndef HB_OPTIMIZE_SIZE"
    modes[COMPACT] = "#elif !defined(HB_NO_UCD_UNASSIGNED)"
    modes[SLOPPY] = "#else"
    modes[None] = "#endif"
else:
    modes[DEFAULT] = ""

for step, text in modes.items():
    print()
    if text:
        print(text)
        print()
    if step is None:
        continue

    compression = compression_level[step]
    logging.info("  Compression=%d:" % compression)

    if step == SLOPPY:
        for i in range(len(gc)):
            if (i % 128) and gc[i] == "Cn":
                gc[i] = gc[i - 1]
        for i in range(len(gc) - 2, -1, -1):
            if ((i + 1) % 128) and gc[i] == "Cn":
                gc[i] = gc[i + 1]
        for i in range(len(sc)):
            if (i % 128) and sc[i] == "Zzzz":
                sc[i] = sc[i - 1]
        for i in range(len(sc) - 2, -1, -1):
            if ((i + 1) % 128) and sc[i] == "Zzzz":
                sc[i] = sc[i + 1]

    code = packTab.Code("_hb_ucd")

    for name, data, default, mapping in datasets:
        sol = packTab.pack_table(
            data, default, mapping=mapping, compression=compression
        )
        logging.info("      Dataset=%-8s FullCost=%d" % (name, sol.fullCost))
        sol.genCode(code, name, private=private, language=language)

    code.print_code(language=language)

    print()

if language.name == "c":
    print("#endif /* HB_UCD_TABLE_HH */")
elif language.name == "rust":
    print("}")
else:
    assert False, "Unknown language: %s" % language.name
print()
print("/* == End of generated table == */")
logging.info("Done.")
