#!/usr/bin/env python3
"""Write hanja.dict from a one-Hanja-per-row UTF-8 source."""

import sys
from pathlib import Path


SOURCE = Path(__file__).with_name("hanja.src")
MAXCANDIDATES = 128


def ishangul(s):
    return len(s) == 1 and 0xAC00 <= ord(s) <= 0xD7A3


def ishanja(s):
    if len(s) != 1:
        return False
    c = ord(s)
    return (0x3400 <= c <= 0x4DBF
            or 0x4E00 <= c <= 0x9FFF
            or 0xF900 <= c <= 0xFAFF)


def read(path):
    comments = []
    table = {}
    seen = set()
    leading = True
    with path.open(encoding="utf-8") as src:
        for lineno, raw in enumerate(src, 1):
            line = raw.rstrip("\r\n")
            if not line:
                continue
            if line.startswith("#"):
                if leading:
                    comments.append(";;" + line[1:])
                continue
            leading = False
            fields = line.split("\t")
            if len(fields) != 2:
                raise ValueError(f"{path}:{lineno}: need Hanja<TAB>reading")
            hanja, reading = fields
            if not ishanja(hanja):
                raise ValueError(f"{path}:{lineno}: need one BMP Hanja character")
            if not ishangul(reading):
                raise ValueError(f"{path}:{lineno}: need one Hangul syllable")
            pair = (hanja, reading)
            if pair in seen:
                raise ValueError(f"{path}:{lineno}: duplicate Hanja reading")
            seen.add(pair)
            table.setdefault(reading, []).append(hanja)
    if not seen:
        raise ValueError(f"{path}: no Hanja readings")
    return comments, table


def main():
    sys.stdout.reconfigure(encoding="utf-8")
    sys.stderr.reconfigure(encoding="utf-8")
    if len(sys.argv) > 2:
        print(f"usage: {sys.argv[0]} [hanja.src]", file=sys.stderr)
        return 2
    path = Path(sys.argv[1]) if len(sys.argv) == 2 else SOURCE
    try:
        comments, table = read(path)
        for line in comments:
            print(line)
        if comments:
            print()
        for reading, candidates in table.items():
            print(f"{reading}\t{' '.join(candidates[:MAXCANDIDATES])}")
    except (OSError, UnicodeError, ValueError) as error:
        print(error, file=sys.stderr)
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main())
