import fontTools.ttLib as ttLib
from fontTools.ttLib.ttVisitor import TTVisitor
from fontTools.misc.textTools import Tag
from array import array


class JsonVisitor(TTVisitor):
    def _open(self, s):
        print(s, file=self.file)
        self._indent += self.indent
        self.comma = False

    def _close(self, s):
        self._indent = self._indent[: -len(self.indent)]
        print("\n%s%s" % (self._indent, s), end="", file=self.file)
        self.comma = True

    def __init__(self, file, indent="  "):
        self.file = file
        self.indent = indent
        self._indent = ""

    def visitObject(self, obj):
        self._open("{")
        super().visitObject(obj)
        if self.comma:
            print(",", end="", file=self.file)
        print(
            '\n%s"type": "%s"' % (self._indent, obj.__class__.__name__),
            end="",
            file=self.file,
        )
        self._close("}")

    def visitAttr(self, obj, attr, value):
        if self.comma:
            print(",", file=self.file)
        print('%s"%s": ' % (self._indent, attr), end="", file=self.file)
        self.visit(value)
        self.comma = True

    def visitList(self, obj, *args, **kwargs):
        self._open("[")
        comma = False
        for value in obj:
            if comma:
                print(",", end="", file=self.file)
                print(file=self.file)
            print(self._indent, end="", file=self.file)
            self.visit(value, *args, **kwargs)
            comma = True
        self._close("]")

    def visitDict(self, obj, *args, **kwargs):
        self._open("{")
        comma = False
        for key, value in obj.items():
            if comma:
                print(",", end="", file=self.file)
                print(file=self.file)
            print('%s"%s": ' % (self._indent, key), end="", file=self.file)
            self.visit(value, *args, **kwargs)
            comma = True
        self._close("}")

    def visitLeaf(self, obj):
        if isinstance(obj, tuple):
            obj = list(obj)
        elif isinstance(obj, bytes):
            obj = list(obj)

        if obj is None:
            s = "null"
        elif obj is True:
            s = "true"
        elif obj is False:
            s = "false"
        else:
            s = repr(obj)

        if s[0] == "'":
            s = '"' + s[1:-1] + '"'

        print("%s" % s, end="", file=self.file)


@JsonVisitor.register(ttLib.TTFont)
def visit(self, font):
    if hasattr(visitor, "font"):
        print("{}", end="", file=self.file)
        return False
    visitor.font = font

    self._open("{")
    for tag in font.keys():
        if self.comma:
            print(",", file=self.file)
        print('\n%s"%s": ' % (self._indent, tag), end="", file=self.file)
        visitor.visit(font[tag])
    self._close("}")

    del visitor.font
    return False


@JsonVisitor.register(ttLib.GlyphOrder)
def visit(self, obj):
    self.visitList(self.font.getGlyphOrder())
    return False


@JsonVisitor.register_attr(ttLib.getTableClass("glyf"), "glyphOrder")
def visit(visitor, obj, attr, value):
    return False


@JsonVisitor.register(ttLib.getTableModule("glyf").GlyphCoordinates)
def visit(self, obj):
    self.visitList(obj)
    return False


@JsonVisitor.register(Tag)
def visit(self, obj):
    print('"%s"' % str(obj), end="", file=self.file)
    return False


@JsonVisitor.register(array)
def visit(self, obj):
    self.visitList(obj)
    return False


@JsonVisitor.register(bytearray)
def visit(self, obj):
    self.visitList(obj)
    return False


if __name__ == "__main__":

    from fontTools.ttLib import TTFont
    import sys

    if len(sys.argv) != 2:
        print("usage: print-json.py font")
        sys.exit()

    font = TTFont(sys.argv[1])

    visitor = JsonVisitor(sys.stdout)
    visitor.visit(font)
