#!/usr/bin/env python3

import fontforge
import os
import sys
import tempfile

SCRIPTS = [('DFLT', ['dflt']), ('cyrl', ['dflt']), ('latn', ['dflt'])]

SUFFIX_TRIGGERS = ("ые", "ёте", "ься", "тся", "ующему", "ого", "его")
SEPARATORS = (" ", ".", ",", "!", "?", ";", ":")
TARGET_GLYPHS = ("🔱", "♆", "ψ", "Ψ", "Ѱ", "У", "⫝", "v")

REPLACEMENTS = [
    ("", suffix_trigger, separator, TARGET_GLYPHS)
    for suffix_trigger in SUFFIX_TRIGGERS
    for separator in SEPARATORS
] + [
    ("", "Р", "ос", ("р",)),
    ("", "Р", "ОС", ("р",)),
    ("р", "О", "С", ("о",)),
    ("ро", "С", "", ("с",)),
    ("", "R", "uss", ("r",))
]

def string_to_glyphs(font, string):
    out = [(font[ord(glyph)].glyphname if ord(glyph) in font else None) for glyph in string]
    if None in out:
        return None
    return out

def replacement_to_glyphs(font, replacement):
    backwards, match, forward, targets = replacement
    backwards = string_to_glyphs(font, backwards)
    match = string_to_glyphs(font, match)
    forward = string_to_glyphs(font, forward)
    targets = [target for target in [string_to_glyphs(font, target) for target in targets] if target is not None and len(target) == 1]
    if backwards is None or match is None or forward is None or not targets:
        return None
    target = targets[0][0]
    return backwards, match, forward, target

def replacements_to_glyphs(font, replacements):
    return [
            replacement
            for replacement in [
                replacement_to_glyphs(font, replacement)
                for replacement in replacements
            ]
            if replacement is not None
    ]

def process_font(font_path):
    font = fontforge.open(font_path)

    replacements = replacements_to_glyphs(font, REPLACEMENTS)
    if not replacements:
        print(f"Skipping {font.fontname}: could not produce a single replacement.")
        font.close()
        return

    font.addLookup('oblomki_liga', 'gsub_ligature', (), [])
    font.addLookupSubtable('oblomki_liga', 'oblomki_liga_subtable')
    font.addLookup('oblomki_calt', 'gsub_contextchain', (), [('calt', SCRIPTS)])
    possub_seen = set()
    for backwards, match, forward, target in replacements:
        possub = '_'.join(match)
        if possub not in possub_seen:
            possub_seen.add(possub)
            font[target].addPosSub('oblomki_liga_subtable', match)
        brule = ' '.join(backwards)
        mrule = ' '.join([match[0], '@<oblomki_liga>'] + match[1:])
        frule = ' '.join(forward)
        rule = ' | '.join([brule, mrule, frule])
        font.addContextualSubtable('oblomki_calt',
                                   'oblomki_calt_subtable_' + '_'.join(backwards + [''] + match + [''] + forward),
                                   'glyph', rule)

    font.generate(font_path)
    print(f"Successfully processed: {font.fontname}")

    font.close()

for filename in sys.argv[1:]:
    try:
        process_font(filename)
    except OSError as e:
        print(f'Could not process {filename}: {e}')
