#!/usr/bin/env python
#
# Copyright (C) 2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
# and distributed under the terms of the FreeType project license,
# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
# indicate that you have read the license and understand and accept it
# fully.

"""Parse modules.cfg and dump its output either as ftmodule.h or a list of
base extensions.
"""

from __future__ import print_function

import argparse
import os
import re
import sys

# Expected input:
#
#  ...
#  FONT_MODULES += <name>
#  HINTING_MODULES += <name>
#  RASTER_MODULES += <name>
#  AUX_MODULES += <name>
#  BASE_EXTENSIONS += <name>
#  ...


def parse_modules_cfg(input_file):

    lists = {
        "FONT_MODULES": [],
        "HINTING_MODULES": [],
        "RASTER_MODULES": [],
        "AUX_MODULES": [],
        "BASE_EXTENSIONS": [],
    }

    for line in input_file.splitlines():
        line = line.rstrip()
        # Ignore empty lines and those that start with a comment.
        if not line or line[0] == "#":
            continue

        items = line.split()
        assert len(items) == 3 and items[1] == "+=", (
            "Unexpected input line [%s]" % line
        )
        assert items[0] in lists, (
            "Unexpected configuration variable name " + items[0]
        )

        lists[items[0]].append(items[2])

    return lists


def generate_ftmodule(lists):
    result = "/* This is a generated file. */\n"
    for driver in lists["FONT_MODULES"]:
        if driver == "sfnt":  # Special case for the sfnt 'driver'.
            result += "FT_USE_MODULE( FT_Module_Class, sfnt_module_class )\n"
            continue

        name = {
            "truetype": "tt",
            "type1": "t1",
            "cid": "t1cid",
            "type42": "t42",
            "winfonts": "winfnt",
        }.get(driver, driver)
        result += (
            "FT_USE_MODULE( FT_Driver_ClassRec, %s_driver_class )\n" % name
        )

    for module in lists["HINTING_MODULES"]:
        result += (
            "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module
        )

    for module in lists["RASTER_MODULES"]:
        name = {
            "raster": "ft_raster1",
            "smooth": "ft_smooth",
        }.get(module)
        result += (
            "FT_USE_MODULE( FT_Renderer_Class, %s_renderer_class )\n" % name
        )

    for module in lists["AUX_MODULES"]:
        if module in ("psaux", "psnames", "otvalid", "gxvalid"):
            result += (
                "FT_USE_MODULE( FT_Module_Class, %s_module_class )\n" % module
            )

    result += "/* EOF */\n"
    return result


def generate_main_modules(lists):
    return "\n".join(
        lists["FONT_MODULES"]
        + lists["HINTING_MODULES"]
        + lists["RASTER_MODULES"]
    )


def generate_aux_modules(lists):
    return "\n".join(lists["AUX_MODULES"])


def generate_base_extensions(lists):
    return "\n".join(lists["BASE_EXTENSIONS"])


def main():
    parser = argparse.ArgumentParser(description=__doc__)

    parser.add_argument(
        "--format",
        required=True,
        choices=(
            "ftmodule.h",
            "main-modules",
            "aux-modules",
            "base-extensions-list",
        ),
        help="Select output format.",
    )

    parser.add_argument(
        "input",
        metavar="CONFIGURE_RAW",
        help="The input configure.raw file to parse.",
    )

    parser.add_argument("--output", help="Output file (default is stdout).")

    args = parser.parse_args()
    with open(args.input) as f:
        input_data = f.read()

    lists = parse_modules_cfg(input_data)

    if args.format == "ftmodule.h":
        result = generate_ftmodule(lists)
    elif args.format == "main-modules":
        result = generate_main_modules(lists)
    elif args.format == "aux-modules":
        result = generate_aux_modules(lists)
    elif args.format == "base-extensions-list":
        result = generate_base_extensions(lists)
    else:
        assert False, "Invalid output format!"

    if args.output:
        with open(args.output, "w") as f:
            f.write(result)
    else:
        print(result)
    return 0


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