#!/usr/bin/env python3
"""Extract Hanja and symbol readings from libhangul data."""

import sys
import unicodedata
from pathlib import Path


def ishangul(s):
    return s != "" and all(0xAC00 <= ord(c) <= 0xD7A3 for c in s)


def isjamo(s):
    return len(s) == 1 and 0x3131 <= ord(s) <= 0x314E


def ishanja(s):
    return s != "" and all(0x3400 <= ord(c) <= 0x4DBF
                           or 0x4E00 <= ord(c) <= 0x9FFF
                           or 0xF900 <= ord(c) <= 0xFAFF for c in s)


def issymbol(s):
    """One rune the popup can draw and a candidate row can carry: not a
    space, which the row separates candidates with, and not a formatting
    character, which would leave a blank candidate to pick."""
    return (len(s) == 1 and not s.isspace() and not ishanja(s)
            and not unicodedata.category(s).startswith("C"))


def keeps(reading, value):
    """A syllable reading gives Hanja; a jamo reading gives a symbol."""
    if ishangul(reading):
        return ishanja(value)
    return isjamo(reading) and issymbol(value)


def extract(src, name):
    comments = []
    entries = []
    seen = set()
    leading = True
    for lineno, raw in enumerate(src, 1):
        line = raw.rstrip("\r\n")
        if not line:
            continue
        if line.startswith("#"):
            if leading:
                comments.append(line.rstrip())
            continue
        leading = False
        fields = line.split(":")
        if len(fields) != 3:
            raise ValueError(f"{name}:{lineno}: need key:value:comment")
        reading, value, _ = fields
        if not keeps(reading, value):
            continue
        pair = (value, reading)
        if pair in seen:
            raise ValueError(f"{name}:{lineno}: duplicate reading")
        seen.add(pair)
        entries.append(pair)
    if not entries:
        raise ValueError(f"{name}: no readings")
    return comments, entries


def main():
    sys.stdin.reconfigure(encoding="utf-8")
    sys.stdout.reconfigure(encoding="utf-8")
    sys.stderr.reconfigure(encoding="utf-8")
    if len(sys.argv) > 2:
        print(f"usage: {sys.argv[0]} [libhangul-hanja.txt]", file=sys.stderr)
        return 2
    src = sys.stdin
    name = "<stdin>"
    try:
        if len(sys.argv) == 2:
            name = sys.argv[1]
            src = Path(name).open(encoding="utf-8")
        comments, entries = extract(src, name)
        for line in comments:
            print(line)
        if comments:
            print()
        for value, reading in entries:
            print(f"{value}\t{reading}")
    except (OSError, UnicodeError, ValueError) as error:
        print(error, file=sys.stderr)
        return 1
    finally:
        if src is not sys.stdin:
            src.close()
    return 0


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