#!/usr/bin/env python
import argparse
from fontFeatures.shaperLib.Buffer import Buffer
from fontFeatures.ttLib import unparse
from fontTools.ttLib import TTFont
from fontFeatures.shaperLib.Shaper import Shaper
from babelfont import Babelfont

parser = argparse.ArgumentParser(description='Test coverage of OT features.')
parser.add_argument(
    "-i", "--index",
    dest="index", type=int, default=-1,
    help="Font index number (required for collections)",
)
parser.add_argument('--verbose', '-V', action="count", dest='verbose',
                    help='Increase verbosity')

parser.add_argument('wordlist', metavar='FILE',
                    help='a list of strings to shape')
parser.add_argument('font', metavar='OTF',
                    help='a font file to test')

args = parser.parse_args()

# Monkeypatch a shaperLib function
def marked_apply_to_buffer(self, buf, stage=None, feature=None, namedclasses={}):
    buf.set_mask(self.flags, self.markFilteringSet, self.markAttachmentSet)
    if feature:
        buf.set_feature_mask(feature)
    i = 0
    while i < len(buf): # (which may change!)
        for r in self.rules:
            if stage and r.stage != stage:
                continue
            buf.set_mask(r.flags, self.markFilteringSet, self.markAttachmentSet)
            if r.would_apply_at_position(buf, i,namedclasses=namedclasses):
                delta = r._do_apply(buf, i, namedclasses=namedclasses)
                self.applied = True
                r.applied = True
                buf.update()
                if delta:
                    i = i + delta
                break
        i = i + 1


if args.font.endswith("c") and args.index == -1:
    print("Must provide -i argument with TrueType/OpenType collection file", file=sys.stderr)
    sys.exit(1)

font = TTFont(args.font, fontNumber=args.index)
ff = unparse(font)
bbfont = Babelfont.open(args.font)

for r in ff.routines:
    r.applied = False
    for rule in r.rules:
        rule.applied = False
    r.apply_to_buffer = marked_apply_to_buffer.__get__(r, type(r))

shaper = Shaper(ff, bbfont)

with open(args.wordlist) as f:
    for line in f:
        buf = Buffer(bbfont, unicodes=line)
        shaper.execute(buf)

marked_lookups = []
marked_rules = []
all_rules = []
for r in ff.routines:
    if r.applied:
        marked_lookups.append(r)
    for rule in r.rules:
        all_rules.append(rule)
        if rule.applied:
            marked_rules.append(rule)

rs = len(ff.routines)
print("Tests covered %i/%i lookups = %.5f%%" % (len(marked_lookups), rs, 100*(len(marked_lookups)/rs)))
print("Tests covered %i/%i rules = %.5f%%" % (len(marked_rules), len(all_rules), 100*len(marked_rules)/len(all_rules)))


if args.verbose:
    print("\nUnused lookups:")
    for r in ff.routines:
        if r.applied:
            continue
        print(r.asFea())
