#! /usr/bin/env python3

from __future__ import print_function
import io
import sys
import os
from os.path import isfile, join as pjoin
from glob import glob
from setuptools import setup, find_packages, Command, Extension
from setuptools.command.build_ext import build_ext as _build_ext
from distutils import log
from distutils.util import convert_path
import subprocess as sp
import contextlib
import re

# Force distutils to use py_compile.compile() function with 'doraise' argument
# set to True, in order to raise an exception on compilation errors
import py_compile
orig_py_compile = py_compile.compile

def doraise_py_compile(file, cfile=None, dfile=None, doraise=False):
	orig_py_compile(file, cfile=cfile, dfile=dfile, doraise=True)

py_compile.compile = doraise_py_compile

setup_requires = []

if {'bdist_wheel'}.intersection(sys.argv):
	setup_requires.append('wheel')

if {'release'}.intersection(sys.argv):
	setup_requires.append('bump2version')

try:
	__import__("cython")
except ImportError:
	has_cython = False
else:
	has_cython = True

env_with_cython = os.environ.get("FONTTOOLS_WITH_CYTHON")
with_cython = (
	True if env_with_cython in {"1", "true", "yes"}
	else False if env_with_cython in {"0", "false", "no"}
	else None
)
# --with-cython/--without-cython options override environment variables
opt_with_cython = {'--with-cython'}.intersection(sys.argv)
opt_without_cython = {'--without-cython'}.intersection(sys.argv)
if opt_with_cython and opt_without_cython:
	sys.exit(
		"error: the options '--with-cython' and '--without-cython' are "
		"mutually exclusive"
	)
elif opt_with_cython:
	sys.argv.remove("--with-cython")
	with_cython = True
elif opt_without_cython:
	sys.argv.remove("--without-cython")
	with_cython = False

if with_cython and not has_cython:
	setup_requires.append("cython")

ext_modules = []
if with_cython is True or (with_cython is None and has_cython):
	ext_modules.append(
		Extension("fontTools.cu2qu.cu2qu", ["Lib/fontTools/cu2qu/cu2qu.py"]),
	)

extras_require = {
	# for fontTools.ufoLib: to read/write UFO fonts
	"ufo": [
		"fs >= 2.2.0, < 3",
	],
	# for fontTools.misc.etree and fontTools.misc.plistlib: use lxml to
	# read/write XML files (faster/safer than built-in ElementTree)
	"lxml": [
		"lxml >= 4.0, < 5",
	],
	# for fontTools.sfnt and fontTools.woff2: to compress/uncompress
	# WOFF 1.0 and WOFF 2.0 webfonts.
	"woff": [
		"brotli >= 1.0.1; platform_python_implementation == 'CPython'",
		"brotlicffi >= 0.8.0; platform_python_implementation != 'CPython'",
		"zopfli >= 0.1.4",
	],
	# for fontTools.unicode and fontTools.unicodedata: to use the latest version
	# of the Unicode Character Database instead of the built-in unicodedata
	# which varies between python versions and may be outdated.
	"unicode": [
		# the unicodedata2 extension module doesn't work on PyPy.
		# Python 3.9 already has Unicode 13.0, so the backport is not needed.
		(
			"unicodedata2 >= 13.0.0; "
			"python_version < '3.9' and platform_python_implementation != 'PyPy'"
		),
	],
	# for graphite type tables in ttLib/tables (Silf, Glat, Gloc)
	"graphite": [
		"lz4 >= 1.7.4.2"
	],
	# for fontTools.interpolatable: to solve the "minimum weight perfect
	# matching problem in bipartite graphs" (aka Assignment problem)
	"interpolatable": [
		# use pure-python alternative on pypy
		"scipy; platform_python_implementation != 'PyPy'",
		"munkres; platform_python_implementation == 'PyPy'",
	],
	# for fontTools.varLib.plot, to visualize DesignSpaceDocument and resulting
	# VariationModel
	"plot": [
		# TODO: figure out the minimum version of matplotlib that we need
		"matplotlib",
	],
	# for fontTools.misc.symfont, module for symbolic font statistics analysis
	"symfont": [
		"sympy",
	],
	# To get file creator and type of Macintosh PostScript Type 1 fonts (macOS only)
	"type1": [
		"xattr; sys_platform == 'darwin'",
	],
	# for fontTools.ttLib.removeOverlaps, to remove overlaps in TTF fonts
	"pathops": [
		"skia-pathops >= 0.5.0",
	],
}
# use a special 'all' key as shorthand to includes all the extra dependencies
extras_require["all"] = sum(extras_require.values(), [])


# Trove classifiers for PyPI
classifiers = {"classifiers": [
	"Development Status :: 5 - Production/Stable",
	"Environment :: Console",
	"Environment :: Other Environment",
	"Intended Audience :: Developers",
	"Intended Audience :: End Users/Desktop",
	"License :: OSI Approved :: MIT License",
	"Natural Language :: English",
	"Operating System :: OS Independent",
	"Programming Language :: Python",
	"Programming Language :: Python :: 2",
	"Programming Language :: Python :: 3",
	"Topic :: Text Processing :: Fonts",
	"Topic :: Multimedia :: Graphics",
	"Topic :: Multimedia :: Graphics :: Graphics Conversion",
]}


# concatenate README.rst and NEWS.rest into long_description so they are
# displayed on the FontTols project page on PyPI
with io.open("README.rst", "r", encoding="utf-8") as readme:
	long_description = readme.read()
long_description += "\nChangelog\n~~~~~~~~~\n\n"
with io.open("NEWS.rst", "r", encoding="utf-8") as changelog:
	long_description += changelog.read()


@contextlib.contextmanager
def capture_logger(name):
	""" Context manager to capture a logger output with a StringIO stream.
	"""
	import logging

	logger = logging.getLogger(name)
	try:
		import StringIO
		stream = StringIO.StringIO()
	except ImportError:
		stream = io.StringIO()
	handler = logging.StreamHandler(stream)
	logger.addHandler(handler)
	try:
		yield stream
	finally:
		logger.removeHandler(handler)


class release(Command):
	"""
	Tag a new release with a single command, using the 'bumpversion' tool
	to update all the version strings in the source code.
	The version scheme conforms to 'SemVer' and PEP 440 specifications.

	Firstly, the pre-release '.devN' suffix is dropped to signal that this is
	a stable release. If '--major' or '--minor' options are passed, the
	the first or second 'semver' digit is also incremented. Major is usually
	for backward-incompatible API changes, while minor is used when adding
	new backward-compatible functionalities. No options imply 'patch' or bug-fix
	release.

	A new header is also added to the changelog file ("NEWS.rst"), containing
	the new version string and the current 'YYYY-MM-DD' date.

	All changes are committed, and an annotated git tag is generated. With the
	--sign option, the tag is GPG-signed with the user's default key.

	Finally, the 'patch' part of the version string is bumped again, and a
	pre-release suffix '.dev0' is appended to mark the opening of a new
	development cycle.

	Links:
	- http://semver.org/
	- https://www.python.org/dev/peps/pep-0440/
	- https://github.com/c4urself/bump2version
	"""

	description = "update version strings for release"

	user_options = [
		("major", None, "bump the first digit (incompatible API changes)"),
		("minor", None, "bump the second digit (new backward-compatible features)"),
		("sign", "s", "make a GPG-signed tag, using the default key"),
		("allow-dirty", None, "don't abort if working directory is dirty"),
	]

	changelog_name = "NEWS.rst"
	version_RE = re.compile("^[0-9]+\.[0-9]+")
	date_fmt = u"%Y-%m-%d"
	header_fmt = u"%s (released %s)"
	commit_message = "Release {new_version}"
	tag_name = "{new_version}"
	version_files = [
		"setup.cfg",
		"setup.py",
		"Lib/fontTools/__init__.py",
	]

	def initialize_options(self):
		self.minor = False
		self.major = False
		self.sign = False
		self.allow_dirty = False

	def finalize_options(self):
		if all([self.major, self.minor]):
			from distutils.errors import DistutilsOptionError
			raise DistutilsOptionError("--major/--minor are mutually exclusive")
		self.part = "major" if self.major else "minor" if self.minor else None

	def run(self):
		if self.part is not None:
			log.info("bumping '%s' version" % self.part)
			self.bumpversion(self.part, commit=False)
			release_version = self.bumpversion(
				"release", commit=False, allow_dirty=True)
		else:
			log.info("stripping pre-release suffix")
			release_version = self.bumpversion("release")
		log.info("  version = %s" % release_version)

		changes = self.format_changelog(release_version)

		self.git_commit(release_version)
		self.git_tag(release_version, changes, self.sign)

		log.info("bumping 'patch' version and pre-release suffix")
		next_dev_version = self.bumpversion('patch', commit=True)
		log.info("  version = %s" % next_dev_version)

	def git_commit(self, version):
		""" Stage and commit all relevant version files, and format the commit
		message with specified 'version' string.
		"""
		files = self.version_files + [self.changelog_name]

		log.info("committing changes")
		for f in files:
			log.info("  %s" % f)
		if self.dry_run:
			return
		sp.check_call(["git", "add"] + files)
		msg = self.commit_message.format(new_version=version)
		sp.check_call(["git", "commit", "-m", msg], stdout=sp.PIPE)

	def git_tag(self, version, message, sign=False):
		""" Create annotated git tag with given 'version' and 'message'.
		Optionally 'sign' the tag with the user's GPG key.
		"""
		log.info("creating %s git tag '%s'" % (
			"signed" if sign else "annotated", version))
		if self.dry_run:
			return
		# create an annotated (or signed) tag from the new version
		tag_opt = "-s" if sign else "-a"
		tag_name = self.tag_name.format(new_version=version)
		proc = sp.Popen(
			["git", "tag", tag_opt, "-F", "-", tag_name], stdin=sp.PIPE)
		# use the latest changes from the changelog file as the tag message
		tag_message = u"%s\n\n%s" % (tag_name, message)
		proc.communicate(tag_message.encode('utf-8'))
		if proc.returncode != 0:
			sys.exit(proc.returncode)

	def bumpversion(self, part, commit=False, message=None, allow_dirty=None):
		""" Run bumpversion.main() with the specified arguments, and return the
		new computed version string (cf. 'bumpversion --help' for more info)
		"""
		import bumpversion.cli

		args = (
			(['--verbose'] if self.verbose > 1 else []) +
			(['--dry-run'] if self.dry_run else []) +
			(['--allow-dirty'] if (allow_dirty or self.allow_dirty) else []) +
			(['--commit'] if commit else ['--no-commit']) +
			(['--message', message] if message is not None else []) +
			['--list', part]
		)
		log.debug("$ bumpversion %s" % " ".join(a.replace(" ", "\\ ") for a in args))

		with capture_logger("bumpversion.list") as out:
			bumpversion.cli.main(args)

		last_line = out.getvalue().splitlines()[-1]
		new_version = last_line.replace("new_version=", "")
		return new_version

	def format_changelog(self, version):
		""" Write new header at beginning of changelog file with the specified
		'version' and the current date.
		Return the changelog content for the current release.
		"""
		from datetime import datetime

		log.info("formatting changelog")

		changes = []
		with io.open(self.changelog_name, "r+", encoding="utf-8") as f:
			for ln in f:
				if self.version_RE.match(ln):
					break
				else:
					changes.append(ln)
			if not self.dry_run:
				f.seek(0)
				content = f.read()
				date = datetime.today().strftime(self.date_fmt)
				f.seek(0)
				header = self.header_fmt % (version, date)
				f.write(header + u"\n" + u"-"*len(header) + u"\n\n" + content)

		return u"".join(changes)


def find_data_files(manpath="share/man"):
	""" Find FontTools's data_files (just man pages at this point).

	By default, we install man pages to "share/man" directory relative to the
	base installation directory for data_files. The latter can be changed with
	the --install-data option of 'setup.py install' sub-command.

	E.g., if the data files installation directory is "/usr", the default man
	page installation directory will be "/usr/share/man".

	You can override this via the $FONTTOOLS_MANPATH environment variable.

	E.g., on some BSD systems man pages are installed to 'man' instead of
	'share/man'; you can export $FONTTOOLS_MANPATH variable just before
	installing:

	$ FONTTOOLS_MANPATH="man" pip install -v .
	    [...]
	    running install_data
	    copying Doc/man/ttx.1 -> /usr/man/man1

	When installing from PyPI, for this variable to have effect you need to
	force pip to install from the source distribution instead of the wheel
	package (otherwise setup.py is not run), by using the --no-binary option:

	$ FONTTOOLS_MANPATH="man" pip install --no-binary=fonttools fonttools

	Note that you can only override the base man path, i.e. without the
	section number (man1, man3, etc.). The latter is always implied to be 1,
	for "general commands".
	"""

	# get base installation directory for man pages
	manpagebase = os.environ.get('FONTTOOLS_MANPATH', convert_path(manpath))
	# all our man pages go to section 1
	manpagedir = pjoin(manpagebase, 'man1')

	manpages = [f for f in glob(pjoin('Doc', 'man', 'man1', '*.1')) if isfile(f)]

	data_files = [(manpagedir, manpages)]
	return data_files


class cython_build_ext(_build_ext):
	"""Compile *.pyx source files to *.c using cythonize if Cython is
	installed and there is a working C compiler, else fall back to pure python dist.
	"""

	def finalize_options(self):
		from Cython.Build import cythonize

		# optionally enable line tracing for test coverage support
		linetrace = os.environ.get("CYTHON_TRACE") == "1"

		self.distribution.ext_modules[:] = cythonize(
			self.distribution.ext_modules,
			force=linetrace or self.force,
			annotate=os.environ.get("CYTHON_ANNOTATE") == "1",
			quiet=not self.verbose,
			compiler_directives={
				"linetrace": linetrace,
				"language_level": 3,
				"embedsignature": True,
			},
		)

		_build_ext.finalize_options(self)

	def build_extensions(self):
		try:
			_build_ext.build_extensions(self)
		except Exception as e:
			if with_cython:
				raise
			from distutils.errors import DistutilsModuleError

			# optional compilation failed: we delete 'ext_modules' and make sure
			# the generated wheel is 'pure'
			del self.distribution.ext_modules[:]
			try:
				bdist_wheel = self.get_finalized_command("bdist_wheel")
			except DistutilsModuleError:
				# 'bdist_wheel' command not available as wheel is not installed
				pass
			else:
				bdist_wheel.root_is_pure = True
			log.error('error: building extensions failed: %s' % e)

cmdclass = {"release": release}

if ext_modules:
    cmdclass["build_ext"] = cython_build_ext


setup_params = dict(
	name="fonttools",
	version="4.25.1",
	description="Tools to manipulate font files",
	author="Just van Rossum",
	author_email="just@letterror.com",
	maintainer="Behdad Esfahbod",
	maintainer_email="behdad@behdad.org",
	url="http://github.com/fonttools/fonttools",
	license="MIT",
	platforms=["Any"],
	python_requires=">=3.6",
	long_description=long_description,
	package_dir={'': 'Lib'},
	packages=find_packages("Lib"),
	include_package_data=True,
	data_files=find_data_files(),
	ext_modules=ext_modules,
	setup_requires=setup_requires,
	extras_require=extras_require,
	entry_points={
		'console_scripts': [
			"fonttools = fontTools.__main__:main",
			"ttx = fontTools.ttx:main",
			"pyftsubset = fontTools.subset:main",
			"pyftmerge = fontTools.merge:main",
		]
	},
	cmdclass=cmdclass,
	**classifiers
)


if __name__ == "__main__":
	setup(**setup_params)
