#!/usr/bin/env python3

# ==========================================================================
# fontname.py
# Copyright 2019 Christopher Simpkins
# MIT License
#
# Dependencies:
#   1) Python 3.6+ interpreter
#   2) fonttools Python library (https://github.com/fonttools/fonttools)
#         - install with `pip3 install fonttools`
#
# Usage:
#   python3 fontname.py [FONT FAMILY NAME] [FONT PATH 1] <FONT PATH ...>
#
# Notes:
#   Use quotes around font family name arguments that include spaces
# ===========================================================================

import os
import sys

from fontTools import ttLib


def main(argv):
    # command argument tests
    print(" ")
    if len(argv) < 2:
        sys.stderr.write(
            f"[fontname.py] ERROR: you did not include enough arguments to the script.{os.linesep}"
        )
        sys.stderr.write(
            f"Usage: python3 fontname.py [FONT FAMILY NAME] [FONT PATH 1] <FONT PATH ...>{os.linesep}"
        )
        sys.exit(1)

    # begin parsing command line arguments
    try:
        font_name = str(argv[0])  # the first argument is the new typeface name
    except Exception as e:
        sys.stderr.write(
            f"[fontname.py] ERROR: Unable to convert argument to string. {e}{os.linesep}"
        )
        sys.exit(1)

    # all remaining arguments on command line are file paths to fonts
    font_path_list = argv[1:]

    # iterate through all paths provided on command line and rename to `font_name` defined by user
    for font_path in font_path_list:
        # test for existence of font file on requested file path
        if not file_exists(font_path):
            sys.stderr.write(
                f"[fontname.py] ERROR: the path '{font_path}' does not appear to be a valid file path.{os.linesep}"
            )
            sys.exit(1)

        tt = ttLib.TTFont(font_path)
        namerecord_list = tt["name"].names

        style = ""

        # determine font style for this file path from name record nameID 2
        for record in namerecord_list:
            if record.nameID == 2:
                style = str(record)
                break

        # test that a style name was found in the OpenType tables of the font
        if len(style) == 0:
            sys.stderr.write(
                f"[fontname.py] Unable to detect the font style from the OpenType name table in '{font_path}'. {os.linesep}"
            )
            sys.stderr.write("Unable to complete execution of the script.")
            sys.exit(1)
        else:
            # used for the Postscript name in the name table (no spaces allowed)
            postscript_font_name = font_name.replace(" ", "")
            # font family name
            nameID1_string = font_name
            nameID16_string = font_name
            # full font name
            nameID4_string = f"{font_name} {style}"
            # Postscript name
            # - no spaces allowed in family name or the PostScript suffix. should be dash delimited
            nameID6_string = f"{postscript_font_name}-{style.replace(' ', '')}"
            # nameID6_string = postscript_font_name + "-" + style.replace(" ", "")

            # modify the opentype table data in memory with updated values
            for record in namerecord_list:
                if record.nameID == 1:
                    record.string = nameID1_string
                elif record.nameID == 4:
                    record.string = nameID4_string
                elif record.nameID == 6:
                    record.string = nameID6_string
                elif record.nameID == 16:
                    record.string = nameID16_string

            # CFF table naming for CFF fonts (only)
            if "CFF " in tt:
                try:
                    cff = tt["CFF "]
                    cff.cff[0].FamilyName = nameID1_string
                    cff.cff[0].FullName = nameID4_string
                    cff.cff.fontNames = [nameID6_string]
                except Exception as e:
                    sys.stderr.write(
                        f"[fontname.py] ERROR: unable to write new names to CFF table: {e}"
                    )

        # write changes to the font file
        try:
            tt.save(font_path)
            print(f"[OK] Updated '{font_path}' with the name '{nameID4_string}'")
        except Exception as e:
            sys.stderr.write(
                f"[fontname.py] ERROR: unable to write new name to OpenType name table for '{font_path}'. {os.linesep}"
            )
            sys.stderr.write(f"{e}{os.linesep}")
            sys.exit(1)


# Utilities


def file_exists(filepath):
    """Tests for existence of a file on the string filepath"""
    return os.path.exists(filepath) and os.path.isfile(filepath)


if __name__ == "__main__":
    main(sys.argv[1:])
