#!/usr/bin/env python3
"""Generate distribution archives for a given FreeType 2 release."""

from __future__ import print_function

import argparse
import atexit
import os
import shutil
import subprocess
import sys
import tempfile

_SCRIPT_DIR = os.path.dirname(__file__)
_TOP_DIR = os.path.abspath(os.path.join(_SCRIPT_DIR, ".."))


def get_cmd_output(cmd, cwd=None):
    """Run a command and return its output as a string."""
    if cwd is not None:
        out = subprocess.check_output(cmd, cwd=cwd)
    else:
        out = subprocess.check_output(cmd)
    return out.decode("utf-8").rstrip()


def is_git_dir_clean(git_dir):
    """Return True iff |git_dir| is a git directory in clean state."""
    out = get_cmd_output(["git", "status", "--porcelain"], cwd=git_dir)
    return len(out) == 0


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

    parser.add_argument(
        "--source_dir", default=_TOP_DIR, help="Source directory path."
    )

    parser.add_argument(
        "--version",
        help=(
            "Specify alternate FreeType version (it is otherwise extracted"
            " from current sources by default)."
        ),
    )

    parser.add_argument(
        "--gnu-config-dir",
        help=(
            "Path of input directory containing recent `config.guess` and"
            " `config.sub` files from GNU config."
        ),
    )

    parser.add_argument(
        "--build-dir",
        help="Specify build directory. Only used for debugging this script.",
    )

    parser.add_argument(
        "--ignore-clean-check",
        action="store_true",
        help=(
            "Do not check for a clean source git repository. Only used for"
            " debugging this script."
        ),
    )

    parser.add_argument(
        "output_dir", help="Output directory for generated archives."
    )

    args = parser.parse_args()

    git_dir = args.source_dir if args.source_dir else _TOP_DIR
    if not args.ignore_clean_check and not is_git_dir_clean(git_dir):
        sys.stderr.write(
            "ERROR: Your git repository is not in a clean state: %s\n"
            % git_dir
        )
        return 1

    if args.version:
        version = args.version
    else:
        # Extract FreeType version from sources.
        version = get_cmd_output(
            [
                sys.executable,
                os.path.join(_SCRIPT_DIR, "extract_freetype_version.py"),
                os.path.join(_TOP_DIR, "include", "freetype", "freetype.h"),
            ]
        )

    # Determine the build directory. This will be a temporary file that is
    # cleaned up on script exit by default, unless --build-dir=DIR is used,
    # in which case we only create and empty the directory, but never remove
    # its content on exit.
    if args.build_dir:
        build_dir = args.build_dir
        if not os.path.exists(build_dir):
            os.makedirs(build_dir)
        else:
            # Remove anything from the build directory, if any.
            for item in os.listdir(build_dir):
                file_path = os.path.join(build_dir, item)
                if os.path.isdir(file_path):
                    shutil.rmtree(file_path)
                else:
                    os.unlink(file_path)
    else:
        # Create a temporary directory, and ensure it is removed on exit.
        build_dir = tempfile.mkdtemp(prefix="freetype-dist-")

        def clean_build_dir():
            shutil.rmtree(build_dir)

        atexit.register(clean_build_dir)

    # Copy all source files known to git into $BUILD_DIR/freetype-$VERSION
    # with the exception of .gitignore and .mailmap files.
    source_files = [
        f
        for f in get_cmd_output(["git", "ls-files"], cwd=git_dir).split("\n")
        if os.path.basename(f) not in (".gitignore", ".mailmap")
    ]

    freetype_dir = "freetype-" + version
    tmp_src_dir = os.path.join(build_dir, freetype_dir)
    os.makedirs(tmp_src_dir)

    for src in source_files:
        dst = os.path.join(tmp_src_dir, src)
        dst_dir = os.path.dirname(dst)
        if not os.path.exists(dst_dir):
            os.makedirs(dst_dir)
        shutil.copyfile(src, dst)

    # Run autogen.sh in directory.
    subprocess.check_call(["/bin/sh", "autogen.sh"], cwd=tmp_src_dir)
    shutil.rmtree(
        os.path.join(tmp_src_dir, "builds", "unix", "autom4te.cache")
    )

    # Copy config.guess and config.sub if possible!
    if args.gnu_config_dir:
        for f in ("config.guess", "config.sub"):
            shutil.copyfile(
                os.path.join(args.gnu_config_dir, f),
                os.path.join(tmp_src_dir, "builds", "unix", f),
            )

    # Generate reference documentation under docs/
    subprocess.check_call(
        [
            sys.executable,
            os.path.join(_SCRIPT_DIR, "generate_reference_docs.py"),
            "--input-dir",
            tmp_src_dir,
            "--version",
            version,
            "--output-dir",
            os.path.join(tmp_src_dir, "docs"),
        ]
    )

    shutil.rmtree(os.path.join(tmp_src_dir, "docs", "markdown"))
    os.unlink(os.path.join(tmp_src_dir, "docs", "mkdocs.yml"))

    # Generate our archives
    freetype_tar = freetype_dir + ".tar"

    subprocess.check_call(
        ["tar", "-H", "ustar", "-chf", freetype_tar, freetype_dir],
        cwd=build_dir,
    )

    subprocess.check_call(
        ["gzip", "-9", "--keep", freetype_tar], cwd=build_dir
    )

    subprocess.check_call(["xz", "--keep", freetype_tar], cwd=build_dir)

    ftwinversion = "ft" + "".join(version.split("."))
    subprocess.check_call(
        ["zip", "-qlr9", ftwinversion + ".zip", freetype_dir], cwd=build_dir
    )

    # Copy file to output directory now.
    if not os.path.exists(args.output_dir):
        os.makedirs(args.output_dir)

    for f in (
        freetype_tar + ".gz",
        freetype_tar + ".xz",
        ftwinversion + ".zip",
    ):
        shutil.copyfile(
            os.path.join(build_dir, f), os.path.join(args.output_dir, f)
        )

    # Done!
    return 0


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