import os
from copy import deepcopy
from os import fsdecode
import logging
import zipfile
import enum
from collections import OrderedDict
import fs
import fs.base
import fs.subfs
import fs.errors
import fs.copy
import fs.osfs
import fs.zipfs
import fs.tempfs
import fs.tools
from fontTools.misc import plistlib
from fontTools.ufoLib.validators import *
from fontTools.ufoLib.filenames import userNameToFileName
from fontTools.ufoLib.converters import convertUFO1OrUFO2KerningToUFO3Kerning
from fontTools.ufoLib.errors import UFOLibError
from fontTools.ufoLib.utils import numberTypes, _VersionTupleEnumMixin

"""
A library for importing .ufo files and their descendants.
Refer to http://unifiedfontobject.com for the UFO specification.

The UFOReader and UFOWriter classes support versions 1, 2 and 3
of the specification.

Sets that list the font info attribute names for the fontinfo.plist
formats are available for external use. These are:
	fontInfoAttributesVersion1
	fontInfoAttributesVersion2
	fontInfoAttributesVersion3

A set listing the fontinfo.plist attributes that were deprecated
in version 2 is available for external use:
	deprecatedFontInfoAttributesVersion2

Functions that do basic validation on values for fontinfo.plist
are available for external use. These are
	validateFontInfoVersion2ValueForAttribute
	validateFontInfoVersion3ValueForAttribute

Value conversion functions are available for converting
fontinfo.plist values between the possible format versions.
	convertFontInfoValueForAttributeFromVersion1ToVersion2
	convertFontInfoValueForAttributeFromVersion2ToVersion1
	convertFontInfoValueForAttributeFromVersion2ToVersion3
	convertFontInfoValueForAttributeFromVersion3ToVersion2
"""

__all__ = [
	"makeUFOPath",
	"UFOLibError",
	"UFOReader",
	"UFOWriter",
	"UFOReaderWriter",
	"UFOFileStructure",
	"fontInfoAttributesVersion1",
	"fontInfoAttributesVersion2",
	"fontInfoAttributesVersion3",
	"deprecatedFontInfoAttributesVersion2",
	"validateFontInfoVersion2ValueForAttribute",
	"validateFontInfoVersion3ValueForAttribute",
	"convertFontInfoValueForAttributeFromVersion1ToVersion2",
	"convertFontInfoValueForAttributeFromVersion2ToVersion1"
]

__version__ = "3.0.0"


logger = logging.getLogger(__name__)


# ---------
# Constants
# ---------

DEFAULT_GLYPHS_DIRNAME = "glyphs"
DATA_DIRNAME = "data"
IMAGES_DIRNAME = "images"
METAINFO_FILENAME = "metainfo.plist"
FONTINFO_FILENAME = "fontinfo.plist"
LIB_FILENAME = "lib.plist"
GROUPS_FILENAME = "groups.plist"
KERNING_FILENAME = "kerning.plist"
FEATURES_FILENAME = "features.fea"
LAYERCONTENTS_FILENAME = "layercontents.plist"
LAYERINFO_FILENAME = "layerinfo.plist"

DEFAULT_LAYER_NAME = "public.default"


class UFOFormatVersion(tuple, _VersionTupleEnumMixin, enum.Enum):
	FORMAT_1_0 = (1, 0)
	FORMAT_2_0 = (2, 0)
	FORMAT_3_0 = (3, 0)


class UFOFileStructure(enum.Enum):
	ZIP = "zip"
	PACKAGE = "package"


# --------------
# Shared Methods
# --------------


class _UFOBaseIO:

	def getFileModificationTime(self, path):
		"""
		Returns the modification time for the file at the given path, as a
		floating point number giving the number of seconds since the epoch.
		The path must be relative to the UFO path.
		Returns None if the file does not exist.
		"""
		try:
			dt = self.fs.getinfo(fsdecode(path), namespaces=["details"]).modified
		except (fs.errors.MissingInfoNamespace, fs.errors.ResourceNotFound):
			return None
		else:
			return dt.timestamp()

	def _getPlist(self, fileName, default=None):
		"""
		Read a property list relative to the UFO filesystem's root.
		Raises UFOLibError if the file is missing and default is None,
		otherwise default is returned.

		The errors that could be raised during the reading of a plist are
		unpredictable and/or too large to list, so, a blind try: except:
		is done. If an exception occurs, a UFOLibError will be raised.
		"""
		try:
			with self.fs.open(fileName, "rb") as f:
				return plistlib.load(f)
		except fs.errors.ResourceNotFound:
			if default is None:
				raise UFOLibError(
					"'%s' is missing on %s. This file is required"
					% (fileName, self.fs)
				)
			else:
				return default
		except Exception as e:
			# TODO(anthrotype): try to narrow this down a little
			raise UFOLibError(
				f"'{fileName}' could not be read on {self.fs}: {e}"
			)

	def _writePlist(self, fileName, obj):
		"""
		Write a property list to a file relative to the UFO filesystem's root.

		Do this sort of atomically, making it harder to corrupt existing files,
		for example when plistlib encounters an error halfway during write.
		This also checks to see if text matches the text that is already in the
		file at path. If so, the file is not rewritten so that the modification
		date is preserved.

		The errors that could be raised during the writing of a plist are
		unpredictable and/or too large to list, so, a blind try: except: is done.
		If an exception occurs, a UFOLibError will be raised.
		"""
		if self._havePreviousFile:
			try:
				data = plistlib.dumps(obj)
			except Exception as e:
				raise UFOLibError(
					"'%s' could not be written on %s because "
					"the data is not properly formatted: %s"
					% (fileName, self.fs, e)
				)
			if self.fs.exists(fileName) and data == self.fs.readbytes(fileName):
				return
			self.fs.writebytes(fileName, data)
		else:
			with self.fs.openbin(fileName, mode="w") as fp:
				try:
					plistlib.dump(obj, fp)
				except Exception as e:
					raise UFOLibError(
						"'%s' could not be written on %s because "
						"the data is not properly formatted: %s"
						% (fileName, self.fs, e)
					)


# ----------
# UFO Reader
# ----------

class UFOReader(_UFOBaseIO):

	"""
	Read the various components of the .ufo.

	By default read data is validated. Set ``validate`` to
	``False`` to not validate the data.
	"""

	def __init__(self, path, validate=True):
		if hasattr(path, "__fspath__"):  # support os.PathLike objects
			path = path.__fspath__()

		if isinstance(path, str):
			structure = _sniffFileStructure(path)
			try:
				if structure is UFOFileStructure.ZIP:
					parentFS = fs.zipfs.ZipFS(path, write=False, encoding="utf-8")
				else:
					parentFS = fs.osfs.OSFS(path)
			except fs.errors.CreateFailed as e:
				raise UFOLibError(f"unable to open '{path}': {e}")

			if structure is UFOFileStructure.ZIP:
				# .ufoz zip files must contain a single root directory, with arbitrary
				# name, containing all the UFO files
				rootDirs = [
					p.name for p in parentFS.scandir("/")
					# exclude macOS metadata contained in zip file
					if p.is_dir and p.name != "__MACOSX"
				]
				if len(rootDirs) == 1:
					# 'ClosingSubFS' ensures that the parent zip file is closed when
					# its root subdirectory is closed
					self.fs = parentFS.opendir(
						rootDirs[0], factory=fs.subfs.ClosingSubFS
					)
				else:
					raise UFOLibError(
						"Expected exactly 1 root directory, found %d" % len(rootDirs)
					)
			else:
				# normal UFO 'packages' are just a single folder
				self.fs = parentFS
			# when passed a path string, we make sure we close the newly opened fs
			# upon calling UFOReader.close method or context manager's __exit__
			self._shouldClose = True
			self._fileStructure = structure
		elif isinstance(path, fs.base.FS):
			filesystem = path
			try:
				filesystem.check()
			except fs.errors.FilesystemClosed:
				raise UFOLibError("the filesystem '%s' is closed" % path)
			else:
				self.fs = filesystem
			try:
				path = filesystem.getsyspath("/")
			except fs.errors.NoSysPath:
				# network or in-memory FS may not map to the local one
				path = str(filesystem)
			# when user passed an already initialized fs instance, it is her
			# responsibility to close it, thus UFOReader.close/__exit__ are no-op
			self._shouldClose = False
			# default to a 'package' structure
			self._fileStructure = UFOFileStructure.PACKAGE
		else:
			raise TypeError(
				"Expected a path string or fs.base.FS object, found '%s'"
				% type(path).__name__
			)
		self._path = fsdecode(path)
		self._validate = validate
		self._upConvertedKerningData = None

		try:
			self.readMetaInfo(validate=validate)
		except UFOLibError:
			self.close()
			raise

	# properties

	def _get_path(self):
		import warnings

		warnings.warn(
			"The 'path' attribute is deprecated; use the 'fs' attribute instead",
			DeprecationWarning,
			stacklevel=2,
		)
		return self._path

	path = property(_get_path, doc="The path of the UFO (DEPRECATED).")

	def _get_formatVersion(self):
		import warnings

		warnings.warn(
			"The 'formatVersion' attribute is deprecated; use the 'formatVersionTuple'",
			DeprecationWarning,
			stacklevel=2,
		)
		return self._formatVersion.major

	formatVersion = property(
		_get_formatVersion,
		doc="The (major) format version of the UFO. DEPRECATED: Use formatVersionTuple"
	)

	@property
	def formatVersionTuple(self):
		"""The (major, minor) format version of the UFO.
		This is determined by reading metainfo.plist during __init__.
		"""
		return self._formatVersion

	def _get_fileStructure(self):
		return self._fileStructure

	fileStructure = property(
		_get_fileStructure,
		doc=(
			"The file structure of the UFO: "
			"either UFOFileStructure.ZIP or UFOFileStructure.PACKAGE"
		)
	)

	# up conversion

	def _upConvertKerning(self, validate):
		"""
		Up convert kerning and groups in UFO 1 and 2.
		The data will be held internally until each bit of data
		has been retrieved. The conversion of both must be done
		at once, so the raw data is cached and an error is raised
		if one bit of data becomes obsolete before it is called.

		``validate`` will validate the data.
		"""
		if self._upConvertedKerningData:
			testKerning = self._readKerning()
			if testKerning != self._upConvertedKerningData["originalKerning"]:
				raise UFOLibError("The data in kerning.plist has been modified since it was converted to UFO 3 format.")
			testGroups = self._readGroups()
			if testGroups != self._upConvertedKerningData["originalGroups"]:
				raise UFOLibError("The data in groups.plist has been modified since it was converted to UFO 3 format.")
		else:
			groups = self._readGroups()
			if validate:
				invalidFormatMessage = "groups.plist is not properly formatted."
				if not isinstance(groups, dict):
					raise UFOLibError(invalidFormatMessage)
				for groupName, glyphList in groups.items():
					if not isinstance(groupName, str):
						raise UFOLibError(invalidFormatMessage)
					elif not isinstance(glyphList, list):
						raise UFOLibError(invalidFormatMessage)
					for glyphName in glyphList:
						if not isinstance(glyphName, str):
							raise UFOLibError(invalidFormatMessage)
			self._upConvertedKerningData = dict(
				kerning={},
				originalKerning=self._readKerning(),
				groups={},
				originalGroups=groups
			)
			# convert kerning and groups
			kerning, groups, conversionMaps = convertUFO1OrUFO2KerningToUFO3Kerning(
				self._upConvertedKerningData["originalKerning"],
				deepcopy(self._upConvertedKerningData["originalGroups"]),
				self.getGlyphSet()
			)
			# store
			self._upConvertedKerningData["kerning"] = kerning
			self._upConvertedKerningData["groups"] = groups
			self._upConvertedKerningData["groupRenameMaps"] = conversionMaps

	# support methods

	def readBytesFromPath(self, path):
		"""
		Returns the bytes in the file at the given path.
		The path must be relative to the UFO's filesystem root.
		Returns None if the file does not exist.
		"""
		try:
			return self.fs.readbytes(fsdecode(path))
		except fs.errors.ResourceNotFound:
			return None

	def getReadFileForPath(self, path, encoding=None):
		"""
		Returns a file (or file-like) object for the file at the given path.
		The path must be relative to the UFO path.
		Returns None if the file does not exist.
		By default the file is opened in binary mode (reads bytes).
		If encoding is passed, the file is opened in text mode (reads str).

		Note: The caller is responsible for closing the open file.
		"""
		path = fsdecode(path)
		try:
			if encoding is None:
				return self.fs.openbin(path)
			else:
				return self.fs.open(path, mode="r", encoding=encoding)
		except fs.errors.ResourceNotFound:
			return None
	# metainfo.plist

	def _readMetaInfo(self, validate=None):
		"""
		Read metainfo.plist and return raw data. Only used for internal operations.

		``validate`` will validate the read data, by default it is set
		to the class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		data = self._getPlist(METAINFO_FILENAME)
		if validate and not isinstance(data, dict):
			raise UFOLibError("metainfo.plist is not properly formatted.")
		try:
			formatVersionMajor = data["formatVersion"]
		except KeyError:
			raise UFOLibError(
				f"Missing required formatVersion in '{METAINFO_FILENAME}' on {self.fs}"
			)
		formatVersionMinor = data.setdefault("formatVersionMinor", 0)

		try:
			formatVersion = UFOFormatVersion((formatVersionMajor, formatVersionMinor))
		except ValueError as e:
			unsupportedMsg = (
				f"Unsupported UFO format ({formatVersionMajor}.{formatVersionMinor}) "
				f"in '{METAINFO_FILENAME}' on {self.fs}"
			)
			if validate:
				from fontTools.ufoLib.errors import UnsupportedUFOFormat

				raise UnsupportedUFOFormat(unsupportedMsg) from e

			formatVersion = UFOFormatVersion.default()
			logger.warning(
				"%s. Assuming the latest supported version (%s). "
				"Some data may be skipped or parsed incorrectly",
				unsupportedMsg, formatVersion
			)
		data["formatVersionTuple"] = formatVersion
		return data

	def readMetaInfo(self, validate=None):
		"""
		Read metainfo.plist and set formatVersion. Only used for internal operations.

		``validate`` will validate the read data, by default it is set
		to the class's validate value, can be overridden.
		"""
		data = self._readMetaInfo(validate=validate)
		self._formatVersion = data["formatVersionTuple"]

	# groups.plist

	def _readGroups(self):
		groups = self._getPlist(GROUPS_FILENAME, {})
		# remove any duplicate glyphs in a kerning group
		for groupName, glyphList in groups.items():
			if groupName.startswith(('public.kern1.', 'public.kern2.')):
				groups[groupName] = list(OrderedDict.fromkeys(glyphList))
		return groups

	def readGroups(self, validate=None):
		"""
		Read groups.plist. Returns a dict.
		``validate`` will validate the read data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		# handle up conversion
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			self._upConvertKerning(validate)
			groups = self._upConvertedKerningData["groups"]
		# normal
		else:
			groups = self._readGroups()
		if validate:
			valid, message = groupsValidator(groups)
			if not valid:
				raise UFOLibError(message)
		return groups

	def getKerningGroupConversionRenameMaps(self, validate=None):
		"""
		Get maps defining the renaming that was done during any
		needed kerning group conversion. This method returns a
		dictionary of this form:

			{
				"side1" : {"old group name" : "new group name"},
				"side2" : {"old group name" : "new group name"}
			}

		When no conversion has been performed, the side1 and side2
		dictionaries will be empty.

		``validate`` will validate the groups, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		if self._formatVersion >= UFOFormatVersion.FORMAT_3_0:
			return dict(side1={}, side2={})
		# use the public group reader to force the load and
		# conversion of the data if it hasn't happened yet.
		self.readGroups(validate=validate)
		return self._upConvertedKerningData["groupRenameMaps"]

	# fontinfo.plist

	def _readInfo(self, validate):
		data = self._getPlist(FONTINFO_FILENAME, {})
		if validate and not isinstance(data, dict):
			raise UFOLibError("fontinfo.plist is not properly formatted.")
		return data

	def readInfo(self, info, validate=None):
		"""
		Read fontinfo.plist. It requires an object that allows
		setting attributes with names that follow the fontinfo.plist
		version 3 specification. This will write the attributes
		defined in the file into the object.

		``validate`` will validate the read data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		infoDict = self._readInfo(validate)
		infoDataToSet = {}
		# version 1
		if self._formatVersion == UFOFormatVersion.FORMAT_1_0:
			for attr in fontInfoAttributesVersion1:
				value = infoDict.get(attr)
				if value is not None:
					infoDataToSet[attr] = value
			infoDataToSet = _convertFontInfoDataVersion1ToVersion2(infoDataToSet)
			infoDataToSet = _convertFontInfoDataVersion2ToVersion3(infoDataToSet)
		# version 2
		elif self._formatVersion == UFOFormatVersion.FORMAT_2_0:
			for attr, dataValidationDict in list(fontInfoAttributesVersion2ValueData.items()):
				value = infoDict.get(attr)
				if value is None:
					continue
				infoDataToSet[attr] = value
			infoDataToSet = _convertFontInfoDataVersion2ToVersion3(infoDataToSet)
		# version 3.x
		elif self._formatVersion.major == UFOFormatVersion.FORMAT_3_0.major:
			for attr, dataValidationDict in list(fontInfoAttributesVersion3ValueData.items()):
				value = infoDict.get(attr)
				if value is None:
					continue
				infoDataToSet[attr] = value
		# unsupported version
		else:
			raise NotImplementedError(self._formatVersion)
		# validate data
		if validate:
			infoDataToSet = validateInfoVersion3Data(infoDataToSet)
		# populate the object
		for attr, value in list(infoDataToSet.items()):
			try:
				setattr(info, attr, value)
			except AttributeError:
				raise UFOLibError("The supplied info object does not support setting a necessary attribute (%s)." % attr)

	# kerning.plist

	def _readKerning(self):
		data = self._getPlist(KERNING_FILENAME, {})
		return data

	def readKerning(self, validate=None):
		"""
		Read kerning.plist. Returns a dict.

		``validate`` will validate the kerning data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		# handle up conversion
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			self._upConvertKerning(validate)
			kerningNested = self._upConvertedKerningData["kerning"]
		# normal
		else:
			kerningNested = self._readKerning()
		if validate:
			valid, message = kerningValidator(kerningNested)
			if not valid:
				raise UFOLibError(message)
		# flatten
		kerning = {}
		for left in kerningNested:
			for right in kerningNested[left]:
				value = kerningNested[left][right]
				kerning[left, right] = value
		return kerning

	# lib.plist

	def readLib(self, validate=None):
		"""
		Read lib.plist. Returns a dict.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		data = self._getPlist(LIB_FILENAME, {})
		if validate:
			valid, message = fontLibValidator(data)
			if not valid:
				raise UFOLibError(message)
		return data

	# features.fea

	def readFeatures(self):
		"""
		Read features.fea. Return a string.
		The returned string is empty if the file is missing.
		"""
		try:
			with self.fs.open(FEATURES_FILENAME, "r", encoding="utf-8") as f:
				return f.read()
		except fs.errors.ResourceNotFound:
			return ""

	# glyph sets & layers

	def _readLayerContents(self, validate):
		"""
		Rebuild the layer contents list by checking what glyphsets
		are available on disk.

		``validate`` will validate the layer contents.
		"""
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			return [(DEFAULT_LAYER_NAME, DEFAULT_GLYPHS_DIRNAME)]
		contents = self._getPlist(LAYERCONTENTS_FILENAME)
		if validate:
			valid, error = layerContentsValidator(contents, self.fs)
			if not valid:
				raise UFOLibError(error)
		return contents

	def getLayerNames(self, validate=None):
		"""
		Get the ordered layer names from layercontents.plist.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		layerContents = self._readLayerContents(validate)
		layerNames = [layerName for layerName, directoryName in layerContents]
		return layerNames

	def getDefaultLayerName(self, validate=None):
		"""
		Get the default layer name from layercontents.plist.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		layerContents = self._readLayerContents(validate)
		for layerName, layerDirectory in layerContents:
			if layerDirectory == DEFAULT_GLYPHS_DIRNAME:
				return layerName
		# this will already have been raised during __init__
		raise UFOLibError("The default layer is not defined in layercontents.plist.")

	def getGlyphSet(self, layerName=None, validateRead=None, validateWrite=None):
		"""
		Return the GlyphSet associated with the
		glyphs directory mapped to layerName
		in the UFO. If layerName is not provided,
		the name retrieved with getDefaultLayerName
		will be used.

		``validateRead`` will validate the read data, by default it is set to the
		class's validate value, can be overridden.
		``validateWrite`` will validate the written data, by default it is set to the
		class's validate value, can be overridden.
		"""
		from fontTools.ufoLib.glifLib import GlyphSet

		if validateRead is None:
			validateRead = self._validate
		if validateWrite is None:
			validateWrite = self._validate
		if layerName is None:
			layerName = self.getDefaultLayerName(validate=validateRead)
		directory = None
		layerContents = self._readLayerContents(validateRead)
		for storedLayerName, storedLayerDirectory in layerContents:
			if layerName == storedLayerName:
				directory = storedLayerDirectory
				break
		if directory is None:
			raise UFOLibError("No glyphs directory is mapped to \"%s\"." % layerName)
		try:
			glyphSubFS = self.fs.opendir(directory)
		except fs.errors.ResourceNotFound:
			raise UFOLibError(
				f"No '{directory}' directory for layer '{layerName}'"
			)
		return GlyphSet(
			glyphSubFS,
			ufoFormatVersion=self._formatVersion,
			validateRead=validateRead,
			validateWrite=validateWrite,
			expectContentsFile=True
		)

	def getCharacterMapping(self, layerName=None, validate=None):
		"""
		Return a dictionary that maps unicode values (ints) to
		lists of glyph names.
		"""
		if validate is None:
			validate = self._validate
		glyphSet = self.getGlyphSet(layerName, validateRead=validate, validateWrite=True)
		allUnicodes = glyphSet.getUnicodes()
		cmap = {}
		for glyphName, unicodes in allUnicodes.items():
			for code in unicodes:
				if code in cmap:
					cmap[code].append(glyphName)
				else:
					cmap[code] = [glyphName]
		return cmap

	# /data

	def getDataDirectoryListing(self):
		"""
		Returns a list of all files in the data directory.
		The returned paths will be relative to the UFO.
		This will not list directory names, only file names.
		Thus, empty directories will be skipped.
		"""
		try:
			self._dataFS = self.fs.opendir(DATA_DIRNAME)
		except fs.errors.ResourceNotFound:
			return []
		except fs.errors.DirectoryExpected:
			raise UFOLibError("The UFO contains a \"data\" file instead of a directory.")
		try:
			# fs Walker.files method returns "absolute" paths (in terms of the
			# root of the 'data' SubFS), so we strip the leading '/' to make
			# them relative
			return [
				p.lstrip("/") for p in self._dataFS.walk.files()
			]
		except fs.errors.ResourceError:
			return []

	def getImageDirectoryListing(self, validate=None):
		"""
		Returns a list of all image file names in
		the images directory. Each of the images will
		have been verified to have the PNG signature.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			return []
		if validate is None:
			validate = self._validate
		try:
			self._imagesFS = imagesFS = self.fs.opendir(IMAGES_DIRNAME)
		except fs.errors.ResourceNotFound:
			return []
		except fs.errors.DirectoryExpected:
			raise UFOLibError("The UFO contains an \"images\" file instead of a directory.")
		result = []
		for path in imagesFS.scandir("/"):
			if path.is_dir:
				# silently skip this as version control
				# systems often have hidden directories
				continue
			if validate:
				with imagesFS.openbin(path.name) as fp:
					valid, error = pngValidator(fileObj=fp)
				if valid:
					result.append(path.name)
			else:
				result.append(path.name)
		return result

	def readData(self, fileName):
		"""
		Return bytes for the file named 'fileName' inside the 'data/' directory.
		"""
		fileName = fsdecode(fileName)
		try:
			try:
				dataFS = self._dataFS
			except AttributeError:
				# in case readData is called before getDataDirectoryListing
				dataFS = self.fs.opendir(DATA_DIRNAME)
			data = dataFS.readbytes(fileName)
		except fs.errors.ResourceNotFound:
			raise UFOLibError(f"No data file named '{fileName}' on {self.fs}")
		return data

	def readImage(self, fileName, validate=None):
		"""
		Return image data for the file named fileName.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			raise UFOLibError(
				f"Reading images is not allowed in UFO {self._formatVersion.major}."
			)
		fileName = fsdecode(fileName)
		try:
			try:
				imagesFS = self._imagesFS
			except AttributeError:
				# in case readImage is called before getImageDirectoryListing
				imagesFS = self.fs.opendir(IMAGES_DIRNAME)
			data = imagesFS.readbytes(fileName)
		except fs.errors.ResourceNotFound:
			raise UFOLibError(f"No image file named '{fileName}' on {self.fs}")
		if validate:
			valid, error = pngValidator(data=data)
			if not valid:
				raise UFOLibError(error)
		return data

	def close(self):
		if self._shouldClose:
			self.fs.close()

	def __enter__(self):
		return self

	def __exit__(self, exc_type, exc_value, exc_tb):
		self.close()


# ----------
# UFO Writer
# ----------

class UFOWriter(UFOReader):

	"""
	Write the various components of the .ufo.

	By default, the written data will be validated before writing. Set ``validate`` to
	``False`` if you do not want to validate the data. Validation can also be overriden
	on a per method level if desired.

	The ``formatVersion`` argument allows to specify the UFO format version as a tuple
	of integers (major, minor), or as a single integer for the major digit only (minor
	is implied as 0). By default the latest formatVersion will be used; currently it's
	3.0, which is equivalent to formatVersion=(3, 0).

	An UnsupportedUFOFormat exception is raised if the requested UFO formatVersion is
	not supported.
	"""

	def __init__(
		self,
		path,
		formatVersion=None,
		fileCreator="com.github.fonttools.ufoLib",
		structure=None,
		validate=True,
	):
		try:
			formatVersion = UFOFormatVersion(formatVersion)
		except ValueError as e:
			from fontTools.ufoLib.errors import UnsupportedUFOFormat

			raise UnsupportedUFOFormat(f"Unsupported UFO format: {formatVersion!r}") from e

		if hasattr(path, "__fspath__"):  # support os.PathLike objects
			path = path.__fspath__()

		if isinstance(path, str):
			# normalize path by removing trailing or double slashes
			path = os.path.normpath(path)
			havePreviousFile = os.path.exists(path)
			if havePreviousFile:
				# ensure we use the same structure as the destination
				existingStructure = _sniffFileStructure(path)
				if structure is not None:
					try:
						structure = UFOFileStructure(structure)
					except ValueError:
						raise UFOLibError(
							"Invalid or unsupported structure: '%s'" % structure
						)
					if structure is not existingStructure:
						raise UFOLibError(
							"A UFO with a different structure (%s) already exists "
							"at the given path: '%s'" % (existingStructure, path)
						)
				else:
					structure = existingStructure
			else:
				# if not exists, default to 'package' structure
				if structure is None:
					structure = UFOFileStructure.PACKAGE
				dirName = os.path.dirname(path)
				if dirName and not os.path.isdir(dirName):
					raise UFOLibError(
						"Cannot write to '%s': directory does not exist" % path
					)
			if structure is UFOFileStructure.ZIP:
				if havePreviousFile:
					# we can't write a zip in-place, so we have to copy its
					# contents to a temporary location and work from there, then
					# upon closing UFOWriter we create the final zip file
					parentFS = fs.tempfs.TempFS()
					with fs.zipfs.ZipFS(path, encoding="utf-8") as origFS:
						fs.copy.copy_fs(origFS, parentFS)
					# if output path is an existing zip, we require that it contains
					# one, and only one, root directory (with arbitrary name), in turn
					# containing all the existing UFO contents
					rootDirs = [
						p.name for p in parentFS.scandir("/")
						# exclude macOS metadata contained in zip file
						if p.is_dir and p.name != "__MACOSX"
					]
					if len(rootDirs) != 1:
						raise UFOLibError(
							"Expected exactly 1 root directory, found %d" % len(rootDirs)
						)
					else:
						# 'ClosingSubFS' ensures that the parent filesystem is closed
						# when its root subdirectory is closed
						self.fs = parentFS.opendir(
							rootDirs[0], factory=fs.subfs.ClosingSubFS
						)
				else:
					# if the output zip file didn't exist, we create the root folder;
					# we name it the same as input 'path', but with '.ufo' extension
					rootDir = os.path.splitext(os.path.basename(path))[0] + ".ufo"
					parentFS = fs.zipfs.ZipFS(path, write=True, encoding="utf-8")
					parentFS.makedir(rootDir)
					self.fs = parentFS.opendir(rootDir, factory=fs.subfs.ClosingSubFS)
			else:
				self.fs = fs.osfs.OSFS(path, create=True)
			self._fileStructure = structure
			self._havePreviousFile = havePreviousFile
			self._shouldClose = True
		elif isinstance(path, fs.base.FS):
			filesystem = path
			try:
				filesystem.check()
			except fs.errors.FilesystemClosed:
				raise UFOLibError("the filesystem '%s' is closed" % path)
			else:
				self.fs = filesystem
			try:
				path = filesystem.getsyspath("/")
			except fs.errors.NoSysPath:
				# network or in-memory FS may not map to the local one
				path = str(filesystem)
			# if passed an FS object, always use 'package' structure
			if structure and structure is not UFOFileStructure.PACKAGE:
				import warnings

				warnings.warn(
					"The 'structure' argument is not used when input is an FS object",
					UserWarning,
					stacklevel=2,
				)
			self._fileStructure = UFOFileStructure.PACKAGE
			# if FS contains a "metainfo.plist", we consider it non-empty
			self._havePreviousFile = filesystem.exists(METAINFO_FILENAME)
			# the user is responsible for closing the FS object
			self._shouldClose = False
		else:
			raise TypeError(
				"Expected a path string or fs object, found %s"
				% type(path).__name__
			)

		# establish some basic stuff
		self._path = fsdecode(path)
		self._formatVersion = formatVersion
		self._fileCreator = fileCreator
		self._downConversionKerningData = None
		self._validate = validate
		# if the file already exists, get the format version.
		# this will be needed for up and down conversion.
		previousFormatVersion = None
		if self._havePreviousFile:
			metaInfo = self._readMetaInfo(validate=validate)
			previousFormatVersion = metaInfo["formatVersionTuple"]
			# catch down conversion
			if previousFormatVersion > formatVersion:
				from fontTools.ufoLib.errors import UnsupportedUFOFormat

				raise UnsupportedUFOFormat(
					"The UFO located at this path is a higher version "
					f"({previousFormatVersion}) than the version ({formatVersion}) "
					"that is trying to be written. This is not supported."
				)
		# handle the layer contents
		self.layerContents = {}
		if previousFormatVersion is not None and previousFormatVersion.major >= 3:
			# already exists
			self.layerContents = OrderedDict(self._readLayerContents(validate))
		else:
			# previous < 3
			# imply the layer contents
			if self.fs.exists(DEFAULT_GLYPHS_DIRNAME):
				self.layerContents = {DEFAULT_LAYER_NAME : DEFAULT_GLYPHS_DIRNAME}
		# write the new metainfo
		self._writeMetaInfo()

	# properties

	def _get_fileCreator(self):
		return self._fileCreator

	fileCreator = property(_get_fileCreator, doc="The file creator of the UFO. This is set into metainfo.plist during __init__.")

	# support methods for file system interaction

	def copyFromReader(self, reader, sourcePath, destPath):
		"""
		Copy the sourcePath in the provided UFOReader to destPath
		in this writer. The paths must be relative. This works with
		both individual files and directories.
		"""
		if not isinstance(reader, UFOReader):
			raise UFOLibError("The reader must be an instance of UFOReader.")
		sourcePath = fsdecode(sourcePath)
		destPath = fsdecode(destPath)
		if not reader.fs.exists(sourcePath):
			raise UFOLibError("The reader does not have data located at \"%s\"." % sourcePath)
		if self.fs.exists(destPath):
			raise UFOLibError("A file named \"%s\" already exists." % destPath)
		# create the destination directory if it doesn't exist
		self.fs.makedirs(fs.path.dirname(destPath), recreate=True)
		if reader.fs.isdir(sourcePath):
			fs.copy.copy_dir(reader.fs, sourcePath, self.fs, destPath)
		else:
			fs.copy.copy_file(reader.fs, sourcePath, self.fs, destPath)

	def writeBytesToPath(self, path, data):
		"""
		Write bytes to a path relative to the UFO filesystem's root.
		If writing to an existing UFO, check to see if data matches the data
		that is already in the file at path; if so, the file is not rewritten
		so that the modification date is preserved.
		If needed, the directory tree for the given path will be built.
		"""
		path = fsdecode(path)
		if self._havePreviousFile:
			if self.fs.isfile(path) and data == self.fs.readbytes(path):
				return
		try:
			self.fs.writebytes(path, data)
		except fs.errors.FileExpected:
			raise UFOLibError("A directory exists at '%s'" % path)
		except fs.errors.ResourceNotFound:
			self.fs.makedirs(fs.path.dirname(path), recreate=True)
			self.fs.writebytes(path, data)

	def getFileObjectForPath(self, path, mode="w", encoding=None):
		"""
		Returns a file (or file-like) object for the
		file at the given path. The path must be relative
		to the UFO path. Returns None if the file does
		not exist and the mode is "r" or "rb.
		An encoding may be passed if the file is opened in text mode.

		Note: The caller is responsible for closing the open file.
		"""
		path = fsdecode(path)
		try:
			return self.fs.open(path, mode=mode, encoding=encoding)
		except fs.errors.ResourceNotFound as e:
			m = mode[0]
			if m == "r":
				# XXX I think we should just let it raise. The docstring,
				# however, says that this returns None if mode is 'r'
				return None
			elif m == "w" or m == "a" or m == "x":
				self.fs.makedirs(fs.path.dirname(path), recreate=True)
				return self.fs.open(path, mode=mode, encoding=encoding)
		except fs.errors.ResourceError as e:
			return UFOLibError(
				f"unable to open '{path}' on {self.fs}: {e}"
			)

	def removePath(self, path, force=False, removeEmptyParents=True):
		"""
		Remove the file (or directory) at path. The path
		must be relative to the UFO.
		Raises UFOLibError if the path doesn't exist.
		If force=True, ignore non-existent paths.
		If the directory where 'path' is located becomes empty, it will
		be automatically removed, unless 'removeEmptyParents' is False.
		"""
		path = fsdecode(path)
		try:
			self.fs.remove(path)
		except fs.errors.FileExpected:
			self.fs.removetree(path)
		except fs.errors.ResourceNotFound:
			if not force:
				raise UFOLibError(
					f"'{path}' does not exist on {self.fs}"
				)
		if removeEmptyParents:
			parent = fs.path.dirname(path)
			if parent:
				fs.tools.remove_empty(self.fs, parent)

	# alias kept for backward compatibility with old API
	removeFileForPath = removePath

	# UFO mod time

	def setModificationTime(self):
		"""
		Set the UFO modification time to the current time.
		This is never called automatically. It is up to the
		caller to call this when finished working on the UFO.
		"""
		path = self._path
		if path is not None and os.path.exists(path):
			try:
				# this may fail on some filesystems (e.g. SMB servers)
				os.utime(path, None)
			except OSError as e:
				logger.warning("Failed to set modified time: %s", e)

	# metainfo.plist

	def _writeMetaInfo(self):
		metaInfo = dict(
			creator=self._fileCreator,
			formatVersion=self._formatVersion.major,
		)
		if self._formatVersion.minor != 0:
			metaInfo["formatVersionMinor"] = self._formatVersion.minor
		self._writePlist(METAINFO_FILENAME, metaInfo)

	# groups.plist

	def setKerningGroupConversionRenameMaps(self, maps):
		"""
		Set maps defining the renaming that should be done
		when writing groups and kerning in UFO 1 and UFO 2.
		This will effectively undo the conversion done when
		UFOReader reads this data. The dictionary should have
		this form:

			{
				"side1" : {"group name to use when writing" : "group name in data"},
				"side2" : {"group name to use when writing" : "group name in data"}
			}

		This is the same form returned by UFOReader's
		getKerningGroupConversionRenameMaps method.
		"""
		if self._formatVersion >= UFOFormatVersion.FORMAT_3_0:
			return # XXX raise an error here
		# flip the dictionaries
		remap = {}
		for side in ("side1", "side2"):
			for writeName, dataName in list(maps[side].items()):
				remap[dataName] = writeName
		self._downConversionKerningData = dict(groupRenameMap=remap)

	def writeGroups(self, groups, validate=None):
		"""
		Write groups.plist. This method requires a
		dict of glyph groups as an argument.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		# validate the data structure
		if validate:
			valid, message = groupsValidator(groups)
			if not valid:
				raise UFOLibError(message)
		# down convert
		if (
			self._formatVersion < UFOFormatVersion.FORMAT_3_0
			and self._downConversionKerningData is not None
		):
			remap = self._downConversionKerningData["groupRenameMap"]
			remappedGroups = {}
			# there are some edge cases here that are ignored:
			# 1. if a group is being renamed to a name that
			#    already exists, the existing group is always
			#    overwritten. (this is why there are two loops
			#    below.) there doesn't seem to be a logical
			#    solution to groups mismatching and overwriting
			#    with the specifiecd group seems like a better
			#    solution than throwing an error.
			# 2. if side 1 and side 2 groups are being renamed
			#    to the same group name there is no check to
			#    ensure that the contents are identical. that
			#    is left up to the caller.
			for name, contents in list(groups.items()):
				if name in remap:
					continue
				remappedGroups[name] = contents
			for name, contents in list(groups.items()):
				if name not in remap:
					continue
				name = remap[name]
				remappedGroups[name] = contents
			groups = remappedGroups
		# pack and write
		groupsNew = {}
		for key, value in groups.items():
			groupsNew[key] = list(value)
		if groupsNew:
			self._writePlist(GROUPS_FILENAME, groupsNew)
		elif self._havePreviousFile:
			self.removePath(GROUPS_FILENAME, force=True, removeEmptyParents=False)

	# fontinfo.plist

	def writeInfo(self, info, validate=None):
		"""
		Write info.plist. This method requires an object
		that supports getting attributes that follow the
		fontinfo.plist version 2 specification. Attributes
		will be taken from the given object and written
		into the file.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		# gather version 3 data
		infoData = {}
		for attr in list(fontInfoAttributesVersion3ValueData.keys()):
			if hasattr(info, attr):
				try:
					value = getattr(info, attr)
				except AttributeError:
					raise UFOLibError("The supplied info object does not support getting a necessary attribute (%s)." % attr)
				if value is None:
					continue
				infoData[attr] = value
		# down convert data if necessary and validate
		if self._formatVersion == UFOFormatVersion.FORMAT_3_0:
			if validate:
				infoData = validateInfoVersion3Data(infoData)
		elif self._formatVersion == UFOFormatVersion.FORMAT_2_0:
			infoData = _convertFontInfoDataVersion3ToVersion2(infoData)
			if validate:
				infoData = validateInfoVersion2Data(infoData)
		elif self._formatVersion == UFOFormatVersion.FORMAT_1_0:
			infoData = _convertFontInfoDataVersion3ToVersion2(infoData)
			if validate:
				infoData = validateInfoVersion2Data(infoData)
			infoData = _convertFontInfoDataVersion2ToVersion1(infoData)
		# write file if there is anything to write
		if infoData:
			self._writePlist(FONTINFO_FILENAME, infoData)

	# kerning.plist

	def writeKerning(self, kerning, validate=None):
		"""
		Write kerning.plist. This method requires a
		dict of kerning pairs as an argument.

		This performs basic structural validation of the kerning,
		but it does not check for compliance with the spec in
		regards to conflicting pairs. The assumption is that the
		kerning data being passed is standards compliant.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		# validate the data structure
		if validate:
			invalidFormatMessage = "The kerning is not properly formatted."
			if not isDictEnough(kerning):
				raise UFOLibError(invalidFormatMessage)
			for pair, value in list(kerning.items()):
				if not isinstance(pair, (list, tuple)):
					raise UFOLibError(invalidFormatMessage)
				if not len(pair) == 2:
					raise UFOLibError(invalidFormatMessage)
				if not isinstance(pair[0], str):
					raise UFOLibError(invalidFormatMessage)
				if not isinstance(pair[1], str):
					raise UFOLibError(invalidFormatMessage)
				if not isinstance(value, numberTypes):
					raise UFOLibError(invalidFormatMessage)
		# down convert
		if (
			self._formatVersion < UFOFormatVersion.FORMAT_3_0
			and self._downConversionKerningData is not None
		):
			remap = self._downConversionKerningData["groupRenameMap"]
			remappedKerning = {}
			for (side1, side2), value in list(kerning.items()):
				side1 = remap.get(side1, side1)
				side2 = remap.get(side2, side2)
				remappedKerning[side1, side2] = value
			kerning = remappedKerning
		# pack and write
		kerningDict = {}
		for left, right in kerning.keys():
			value = kerning[left, right]
			if left not in kerningDict:
				kerningDict[left] = {}
			kerningDict[left][right] = value
		if kerningDict:
			self._writePlist(KERNING_FILENAME, kerningDict)
		elif self._havePreviousFile:
			self.removePath(KERNING_FILENAME, force=True, removeEmptyParents=False)

	# lib.plist

	def writeLib(self, libDict, validate=None):
		"""
		Write lib.plist. This method requires a
		lib dict as an argument.

		``validate`` will validate the data, by default it is set to the
		class's validate value, can be overridden.
		"""
		if validate is None:
			validate = self._validate
		if validate:
			valid, message = fontLibValidator(libDict)
			if not valid:
				raise UFOLibError(message)
		if libDict:
			self._writePlist(LIB_FILENAME, libDict)
		elif self._havePreviousFile:
			self.removePath(LIB_FILENAME, force=True, removeEmptyParents=False)

	# features.fea

	def writeFeatures(self, features, validate=None):
		"""
		Write features.fea. This method requires a
		features string as an argument.
		"""
		if validate is None:
			validate = self._validate
		if self._formatVersion == UFOFormatVersion.FORMAT_1_0:
			raise UFOLibError("features.fea is not allowed in UFO Format Version 1.")
		if validate:
			if not isinstance(features, str):
				raise UFOLibError("The features are not text.")
		if features:
			self.writeBytesToPath(FEATURES_FILENAME, features.encode("utf8"))
		elif self._havePreviousFile:
			self.removePath(FEATURES_FILENAME, force=True, removeEmptyParents=False)

	# glyph sets & layers

	def writeLayerContents(self, layerOrder=None, validate=None):
		"""
		Write the layercontents.plist file. This method  *must* be called
		after all glyph sets have been written.
		"""
		if validate is None:
			validate = self._validate
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			return
		if layerOrder is not None:
			newOrder = []
			for layerName in layerOrder:
				if layerName is None:
					layerName = DEFAULT_LAYER_NAME
				newOrder.append(layerName)
			layerOrder = newOrder
		else:
			layerOrder = list(self.layerContents.keys())
		if validate and set(layerOrder) != set(self.layerContents.keys()):
			raise UFOLibError("The layer order content does not match the glyph sets that have been created.")
		layerContents = [(layerName, self.layerContents[layerName]) for layerName in layerOrder]
		self._writePlist(LAYERCONTENTS_FILENAME, layerContents)

	def _findDirectoryForLayerName(self, layerName):
		foundDirectory = None
		for existingLayerName, directoryName in list(self.layerContents.items()):
			if layerName is None and directoryName == DEFAULT_GLYPHS_DIRNAME:
				foundDirectory = directoryName
				break
			elif existingLayerName == layerName:
				foundDirectory = directoryName
				break
		if not foundDirectory:
			raise UFOLibError("Could not locate a glyph set directory for the layer named %s." % layerName)
		return foundDirectory

	def getGlyphSet(
		self,
		layerName=None,
		defaultLayer=True,
		glyphNameToFileNameFunc=None,
		validateRead=None,
		validateWrite=None,
		expectContentsFile=False,
	):
		"""
		Return the GlyphSet object associated with the
		appropriate glyph directory in the .ufo.
		If layerName is None, the default glyph set
		will be used. The defaultLayer flag indictes
		that the layer should be saved into the default
		glyphs directory.

		``validateRead`` will validate the read data, by default it is set to the
		class's validate value, can be overridden.
		``validateWrte`` will validate the written data, by default it is set to the
		class's validate value, can be overridden.
		``expectContentsFile`` will raise a GlifLibError if a contents.plist file is
		not found on the glyph set file system. This should be set to ``True`` if you
		are reading an existing UFO and ``False`` if you use ``getGlyphSet`` to create
		a fresh	glyph set.
		"""
		if validateRead is None:
			validateRead = self._validate
		if validateWrite is None:
			validateWrite = self._validate
		# only default can be written in < 3
		if (
			self._formatVersion < UFOFormatVersion.FORMAT_3_0
			and (not defaultLayer or layerName is not None)
		):
			raise UFOLibError(
				f"Only the default layer can be writen in UFO {self._formatVersion.major}."
			)
		# locate a layer name when None has been given
		if layerName is None and defaultLayer:
			for existingLayerName, directory in self.layerContents.items():
				if directory == DEFAULT_GLYPHS_DIRNAME:
					layerName = existingLayerName
			if layerName is None:
				layerName = DEFAULT_LAYER_NAME
		elif layerName is None and not defaultLayer:
			raise UFOLibError("A layer name must be provided for non-default layers.")
		# move along to format specific writing
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			return self._getDefaultGlyphSet(
				validateRead,
				validateWrite,
				glyphNameToFileNameFunc=glyphNameToFileNameFunc,
				expectContentsFile=expectContentsFile
			)
		elif self._formatVersion.major == UFOFormatVersion.FORMAT_3_0.major:
			return self._getGlyphSetFormatVersion3(
				validateRead,
				validateWrite,
				layerName=layerName,
				defaultLayer=defaultLayer,
				glyphNameToFileNameFunc=glyphNameToFileNameFunc,
				expectContentsFile=expectContentsFile,
			)
		else:
			raise NotImplementedError(self._formatVersion)

	def _getDefaultGlyphSet(
		self,
		validateRead,
		validateWrite,
		glyphNameToFileNameFunc=None,
		expectContentsFile=False,
	):
		from fontTools.ufoLib.glifLib import GlyphSet

		glyphSubFS = self.fs.makedir(DEFAULT_GLYPHS_DIRNAME, recreate=True)
		return GlyphSet(
			glyphSubFS,
			glyphNameToFileNameFunc=glyphNameToFileNameFunc,
			ufoFormatVersion=self._formatVersion,
			validateRead=validateRead,
			validateWrite=validateWrite,
			expectContentsFile=expectContentsFile,
		)

	def _getGlyphSetFormatVersion3(
		self,
		validateRead,
		validateWrite,
		layerName=None,
		defaultLayer=True,
		glyphNameToFileNameFunc=None,
		expectContentsFile=False,
	):
		from fontTools.ufoLib.glifLib import GlyphSet

		# if the default flag is on, make sure that the default in the file
		# matches the default being written. also make sure that this layer
		# name is not already linked to a non-default layer.
		if defaultLayer:
			for existingLayerName, directory in self.layerContents.items():
				if directory == DEFAULT_GLYPHS_DIRNAME:
					if existingLayerName != layerName:
						raise UFOLibError(
							"Another layer ('%s') is already mapped to the default directory."
							% existingLayerName
						)
				elif existingLayerName == layerName:
					raise UFOLibError("The layer name is already mapped to a non-default layer.")
		# get an existing directory name
		if layerName in self.layerContents:
			directory = self.layerContents[layerName]
		# get a  new directory name
		else:
			if defaultLayer:
				directory = DEFAULT_GLYPHS_DIRNAME
			else:
				# not caching this could be slightly expensive,
				# but caching it will be cumbersome
				existing = {d.lower() for d in self.layerContents.values()}
				directory = userNameToFileName(layerName, existing=existing, prefix="glyphs.")
		# make the directory
		glyphSubFS = self.fs.makedir(directory, recreate=True)
		# store the mapping
		self.layerContents[layerName] = directory
		# load the glyph set
		return GlyphSet(
			glyphSubFS,
			glyphNameToFileNameFunc=glyphNameToFileNameFunc,
			ufoFormatVersion=self._formatVersion,
			validateRead=validateRead,
			validateWrite=validateWrite,
			expectContentsFile=expectContentsFile,
		)

	def renameGlyphSet(self, layerName, newLayerName, defaultLayer=False):
		"""
		Rename a glyph set.

		Note: if a GlyphSet object has already been retrieved for
		layerName, it is up to the caller to inform that object that
		the directory it represents has changed.
		"""
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			# ignore renaming glyph sets for UFO1 UFO2
			# just write the data from the default layer
			return
		# the new and old names can be the same
		# as long as the default is being switched
		if layerName == newLayerName:
			# if the default is off and the layer is already not the default, skip
			if self.layerContents[layerName] != DEFAULT_GLYPHS_DIRNAME and not defaultLayer:
				return
			# if the default is on and the layer is already the default, skip
			if self.layerContents[layerName] == DEFAULT_GLYPHS_DIRNAME and defaultLayer:
				return
		else:
			# make sure the new layer name doesn't already exist
			if newLayerName is None:
				newLayerName = DEFAULT_LAYER_NAME
			if newLayerName in self.layerContents:
				raise UFOLibError("A layer named %s already exists." % newLayerName)
			# make sure the default layer doesn't already exist
			if defaultLayer and DEFAULT_GLYPHS_DIRNAME in self.layerContents.values():
				raise UFOLibError("A default layer already exists.")
		# get the paths
		oldDirectory = self._findDirectoryForLayerName(layerName)
		if defaultLayer:
			newDirectory = DEFAULT_GLYPHS_DIRNAME
		else:
			existing = {name.lower() for name in self.layerContents.values()}
			newDirectory = userNameToFileName(newLayerName, existing=existing, prefix="glyphs.")
		# update the internal mapping
		del self.layerContents[layerName]
		self.layerContents[newLayerName] = newDirectory
		# do the file system copy
		self.fs.movedir(oldDirectory, newDirectory, create=True)

	def deleteGlyphSet(self, layerName):
		"""
		Remove the glyph set matching layerName.
		"""
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			# ignore deleting glyph sets for UFO1 UFO2 as there are no layers
			# just write the data from the default layer
			return
		foundDirectory = self._findDirectoryForLayerName(layerName)
		self.removePath(foundDirectory, removeEmptyParents=False)
		del self.layerContents[layerName]

	def writeData(self, fileName, data):
		"""
		Write data to fileName in the 'data' directory.
		The data must be a bytes string.
		"""
		self.writeBytesToPath(f"{DATA_DIRNAME}/{fsdecode(fileName)}", data)

	def removeData(self, fileName):
		"""
		Remove the file named fileName from the data directory.
		"""
		self.removePath(f"{DATA_DIRNAME}/{fsdecode(fileName)}")

	# /images

	def writeImage(self, fileName, data, validate=None):
		"""
		Write data to fileName in the images directory.
		The data must be a valid PNG.
		"""
		if validate is None:
			validate = self._validate
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			raise UFOLibError(
				f"Images are not allowed in UFO {self._formatVersion.major}."
			)
		fileName = fsdecode(fileName)
		if validate:
			valid, error = pngValidator(data=data)
			if not valid:
				raise UFOLibError(error)
		self.writeBytesToPath(f"{IMAGES_DIRNAME}/{fileName}", data)

	def removeImage(self, fileName, validate=None):  # XXX remove unused 'validate'?
		"""
		Remove the file named fileName from the
		images directory.
		"""
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			raise UFOLibError(
				f"Images are not allowed in UFO {self._formatVersion.major}."
			)
		self.removePath(f"{IMAGES_DIRNAME}/{fsdecode(fileName)}")

	def copyImageFromReader(self, reader, sourceFileName, destFileName, validate=None):
		"""
		Copy the sourceFileName in the provided UFOReader to destFileName
		in this writer. This uses the most memory efficient method possible
		for copying the data possible.
		"""
		if validate is None:
			validate = self._validate
		if self._formatVersion < UFOFormatVersion.FORMAT_3_0:
			raise UFOLibError(
				f"Images are not allowed in UFO {self._formatVersion.major}."
			)
		sourcePath = f"{IMAGES_DIRNAME}/{fsdecode(sourceFileName)}"
		destPath = f"{IMAGES_DIRNAME}/{fsdecode(destFileName)}"
		self.copyFromReader(reader, sourcePath, destPath)

	def close(self):
		if self._havePreviousFile and self._fileStructure is UFOFileStructure.ZIP:
			# if we are updating an existing zip file, we can now compress the
			# contents of the temporary filesystem in the destination path
			rootDir = os.path.splitext(os.path.basename(self._path))[0] + ".ufo"
			with fs.zipfs.ZipFS(self._path, write=True, encoding="utf-8") as destFS:
				fs.copy.copy_fs(self.fs, destFS.makedir(rootDir))
		super().close()


# just an alias, makes it more explicit
UFOReaderWriter = UFOWriter


# ----------------
# Helper Functions
# ----------------


def _sniffFileStructure(ufo_path):
	"""Return UFOFileStructure.ZIP if the UFO at path 'ufo_path' (str)
	is a zip file, else return UFOFileStructure.PACKAGE if 'ufo_path' is a
	directory.
	Raise UFOLibError if it is a file with unknown structure, or if the path
	does not exist.
	"""
	if zipfile.is_zipfile(ufo_path):
		return UFOFileStructure.ZIP
	elif os.path.isdir(ufo_path):
		return UFOFileStructure.PACKAGE
	elif os.path.isfile(ufo_path):
		raise UFOLibError(
			"The specified UFO does not have a known structure: '%s'" % ufo_path
		)
	else:
		raise UFOLibError("No such file or directory: '%s'" % ufo_path)


def makeUFOPath(path):
	"""
	Return a .ufo pathname.

	>>> makeUFOPath("directory/something.ext") == (
	... 	os.path.join('directory', 'something.ufo'))
	True
	>>> makeUFOPath("directory/something.another.thing.ext") == (
	... 	os.path.join('directory', 'something.another.thing.ufo'))
	True
	"""
	dir, name = os.path.split(path)
	name = ".".join([".".join(name.split(".")[:-1]), "ufo"])
	return os.path.join(dir, name)

# ----------------------
# fontinfo.plist Support
# ----------------------

# Version Validators

# There is no version 1 validator and there shouldn't be.
# The version 1 spec was very loose and there were numerous
# cases of invalid values.

def validateFontInfoVersion2ValueForAttribute(attr, value):
	"""
	This performs very basic validation of the value for attribute
	following the UFO 2 fontinfo.plist specification. The results
	of this should not be interpretted as *correct* for the font
	that they are part of. This merely indicates that the value
	is of the proper type and, where the specification defines
	a set range of possible values for an attribute, that the
	value is in the accepted range.
	"""
	dataValidationDict = fontInfoAttributesVersion2ValueData[attr]
	valueType = dataValidationDict.get("type")
	validator = dataValidationDict.get("valueValidator")
	valueOptions = dataValidationDict.get("valueOptions")
	# have specific options for the validator
	if valueOptions is not None:
		isValidValue = validator(value, valueOptions)
	# no specific options
	else:
		if validator == genericTypeValidator:
			isValidValue = validator(value, valueType)
		else:
			isValidValue = validator(value)
	return isValidValue

def validateInfoVersion2Data(infoData):
	"""
	This performs very basic validation of the value for infoData
	following the UFO 2 fontinfo.plist specification. The results
	of this should not be interpretted as *correct* for the font
	that they are part of. This merely indicates that the values
	are of the proper type and, where the specification defines
	a set range of possible values for an attribute, that the
	value is in the accepted range.
	"""
	validInfoData = {}
	for attr, value in list(infoData.items()):
		isValidValue = validateFontInfoVersion2ValueForAttribute(attr, value)
		if not isValidValue:
			raise UFOLibError(f"Invalid value for attribute {attr} ({value!r}).")
		else:
			validInfoData[attr] = value
	return validInfoData

def validateFontInfoVersion3ValueForAttribute(attr, value):
	"""
	This performs very basic validation of the value for attribute
	following the UFO 3 fontinfo.plist specification. The results
	of this should not be interpretted as *correct* for the font
	that they are part of. This merely indicates that the value
	is of the proper type and, where the specification defines
	a set range of possible values for an attribute, that the
	value is in the accepted range.
	"""
	dataValidationDict = fontInfoAttributesVersion3ValueData[attr]
	valueType = dataValidationDict.get("type")
	validator = dataValidationDict.get("valueValidator")
	valueOptions = dataValidationDict.get("valueOptions")
	# have specific options for the validator
	if valueOptions is not None:
		isValidValue = validator(value, valueOptions)
	# no specific options
	else:
		if validator == genericTypeValidator:
			isValidValue = validator(value, valueType)
		else:
			isValidValue = validator(value)
	return isValidValue

def validateInfoVersion3Data(infoData):
	"""
	This performs very basic validation of the value for infoData
	following the UFO 3 fontinfo.plist specification. The results
	of this should not be interpretted as *correct* for the font
	that they are part of. This merely indicates that the values
	are of the proper type and, where the specification defines
	a set range of possible values for an attribute, that the
	value is in the accepted range.
	"""
	validInfoData = {}
	for attr, value in list(infoData.items()):
		isValidValue = validateFontInfoVersion3ValueForAttribute(attr, value)
		if not isValidValue:
			raise UFOLibError(f"Invalid value for attribute {attr} ({value!r}).")
		else:
			validInfoData[attr] = value
	return validInfoData

# Value Options

fontInfoOpenTypeHeadFlagsOptions = list(range(0, 15))
fontInfoOpenTypeOS2SelectionOptions = [1, 2, 3, 4, 7, 8, 9]
fontInfoOpenTypeOS2UnicodeRangesOptions = list(range(0, 128))
fontInfoOpenTypeOS2CodePageRangesOptions = list(range(0, 64))
fontInfoOpenTypeOS2TypeOptions = [0, 1, 2, 3, 8, 9]

# Version Attribute Definitions
# This defines the attributes, types and, in some
# cases the possible values, that can exist is
# fontinfo.plist.

fontInfoAttributesVersion1 = {
	"familyName",
	"styleName",
	"fullName",
	"fontName",
	"menuName",
	"fontStyle",
	"note",
	"versionMajor",
	"versionMinor",
	"year",
	"copyright",
	"notice",
	"trademark",
	"license",
	"licenseURL",
	"createdBy",
	"designer",
	"designerURL",
	"vendorURL",
	"unitsPerEm",
	"ascender",
	"descender",
	"capHeight",
	"xHeight",
	"defaultWidth",
	"slantAngle",
	"italicAngle",
	"widthName",
	"weightName",
	"weightValue",
	"fondName",
	"otFamilyName",
	"otStyleName",
	"otMacName",
	"msCharSet",
	"fondID",
	"uniqueID",
	"ttVendor",
	"ttUniqueID",
	"ttVersion",
}

fontInfoAttributesVersion2ValueData = {
	"familyName"							: dict(type=str),
	"styleName"								: dict(type=str),
	"styleMapFamilyName"					: dict(type=str),
	"styleMapStyleName"						: dict(type=str, valueValidator=fontInfoStyleMapStyleNameValidator),
	"versionMajor"							: dict(type=int),
	"versionMinor"							: dict(type=int),
	"year"									: dict(type=int),
	"copyright"								: dict(type=str),
	"trademark"								: dict(type=str),
	"unitsPerEm"							: dict(type=(int, float)),
	"descender"								: dict(type=(int, float)),
	"xHeight"								: dict(type=(int, float)),
	"capHeight"								: dict(type=(int, float)),
	"ascender"								: dict(type=(int, float)),
	"italicAngle"							: dict(type=(float, int)),
	"note"									: dict(type=str),
	"openTypeHeadCreated"					: dict(type=str, valueValidator=fontInfoOpenTypeHeadCreatedValidator),
	"openTypeHeadLowestRecPPEM"				: dict(type=(int, float)),
	"openTypeHeadFlags"						: dict(type="integerList", valueValidator=genericIntListValidator, valueOptions=fontInfoOpenTypeHeadFlagsOptions),
	"openTypeHheaAscender"					: dict(type=(int, float)),
	"openTypeHheaDescender"					: dict(type=(int, float)),
	"openTypeHheaLineGap"					: dict(type=(int, float)),
	"openTypeHheaCaretSlopeRise"			: dict(type=int),
	"openTypeHheaCaretSlopeRun"				: dict(type=int),
	"openTypeHheaCaretOffset"				: dict(type=(int, float)),
	"openTypeNameDesigner"					: dict(type=str),
	"openTypeNameDesignerURL"				: dict(type=str),
	"openTypeNameManufacturer"				: dict(type=str),
	"openTypeNameManufacturerURL"			: dict(type=str),
	"openTypeNameLicense"					: dict(type=str),
	"openTypeNameLicenseURL"				: dict(type=str),
	"openTypeNameVersion"					: dict(type=str),
	"openTypeNameUniqueID"					: dict(type=str),
	"openTypeNameDescription"				: dict(type=str),
	"openTypeNamePreferredFamilyName"		: dict(type=str),
	"openTypeNamePreferredSubfamilyName"	: dict(type=str),
	"openTypeNameCompatibleFullName"		: dict(type=str),
	"openTypeNameSampleText"				: dict(type=str),
	"openTypeNameWWSFamilyName"				: dict(type=str),
	"openTypeNameWWSSubfamilyName"			: dict(type=str),
	"openTypeOS2WidthClass"					: dict(type=int, valueValidator=fontInfoOpenTypeOS2WidthClassValidator),
	"openTypeOS2WeightClass"				: dict(type=int, valueValidator=fontInfoOpenTypeOS2WeightClassValidator),
	"openTypeOS2Selection"					: dict(type="integerList", valueValidator=genericIntListValidator, valueOptions=fontInfoOpenTypeOS2SelectionOptions),
	"openTypeOS2VendorID"					: dict(type=str),
	"openTypeOS2Panose"						: dict(type="integerList", valueValidator=fontInfoVersion2OpenTypeOS2PanoseValidator),
	"openTypeOS2FamilyClass"				: dict(type="integerList", valueValidator=fontInfoOpenTypeOS2FamilyClassValidator),
	"openTypeOS2UnicodeRanges"				: dict(type="integerList", valueValidator=genericIntListValidator, valueOptions=fontInfoOpenTypeOS2UnicodeRangesOptions),
	"openTypeOS2CodePageRanges"				: dict(type="integerList", valueValidator=genericIntListValidator, valueOptions=fontInfoOpenTypeOS2CodePageRangesOptions),
	"openTypeOS2TypoAscender"				: dict(type=(int, float)),
	"openTypeOS2TypoDescender"				: dict(type=(int, float)),
	"openTypeOS2TypoLineGap"				: dict(type=(int, float)),
	"openTypeOS2WinAscent"					: dict(type=(int, float)),
	"openTypeOS2WinDescent"					: dict(type=(int, float)),
	"openTypeOS2Type"						: dict(type="integerList", valueValidator=genericIntListValidator, valueOptions=fontInfoOpenTypeOS2TypeOptions),
	"openTypeOS2SubscriptXSize"				: dict(type=(int, float)),
	"openTypeOS2SubscriptYSize"				: dict(type=(int, float)),
	"openTypeOS2SubscriptXOffset"			: dict(type=(int, float)),
	"openTypeOS2SubscriptYOffset"			: dict(type=(int, float)),
	"openTypeOS2SuperscriptXSize"			: dict(type=(int, float)),
	"openTypeOS2SuperscriptYSize"			: dict(type=(int, float)),
	"openTypeOS2SuperscriptXOffset"			: dict(type=(int, float)),
	"openTypeOS2SuperscriptYOffset"			: dict(type=(int, float)),
	"openTypeOS2StrikeoutSize"				: dict(type=(int, float)),
	"openTypeOS2StrikeoutPosition"			: dict(type=(int, float)),
	"openTypeVheaVertTypoAscender"			: dict(type=(int, float)),
	"openTypeVheaVertTypoDescender"			: dict(type=(int, float)),
	"openTypeVheaVertTypoLineGap"			: dict(type=(int, float)),
	"openTypeVheaCaretSlopeRise"			: dict(type=int),
	"openTypeVheaCaretSlopeRun"				: dict(type=int),
	"openTypeVheaCaretOffset"				: dict(type=(int, float)),
	"postscriptFontName"					: dict(type=str),
	"postscriptFullName"					: dict(type=str),
	"postscriptSlantAngle"					: dict(type=(float, int)),
	"postscriptUniqueID"					: dict(type=int),
	"postscriptUnderlineThickness"			: dict(type=(int, float)),
	"postscriptUnderlinePosition"			: dict(type=(int, float)),
	"postscriptIsFixedPitch"				: dict(type=bool),
	"postscriptBlueValues"					: dict(type="integerList", valueValidator=fontInfoPostscriptBluesValidator),
	"postscriptOtherBlues"					: dict(type="integerList", valueValidator=fontInfoPostscriptOtherBluesValidator),
	"postscriptFamilyBlues"					: dict(type="integerList", valueValidator=fontInfoPostscriptBluesValidator),
	"postscriptFamilyOtherBlues"			: dict(type="integerList", valueValidator=fontInfoPostscriptOtherBluesValidator),
	"postscriptStemSnapH"					: dict(type="integerList", valueValidator=fontInfoPostscriptStemsValidator),
	"postscriptStemSnapV"					: dict(type="integerList", valueValidator=fontInfoPostscriptStemsValidator),
	"postscriptBlueFuzz"					: dict(type=(int, float)),
	"postscriptBlueShift"					: dict(type=(int, float)),
	"postscriptBlueScale"					: dict(type=(float, int)),
	"postscriptForceBold"					: dict(type=bool),
	"postscriptDefaultWidthX"				: dict(type=(int, float)),
	"postscriptNominalWidthX"				: dict(type=(int, float)),
	"postscriptWeightName"					: dict(type=str),
	"postscriptDefaultCharacter"			: dict(type=str),
	"postscriptWindowsCharacterSet"			: dict(type=int, valueValidator=fontInfoPostscriptWindowsCharacterSetValidator),
	"macintoshFONDFamilyID"					: dict(type=int),
	"macintoshFONDName"						: dict(type=str),
}
fontInfoAttributesVersion2 = set(fontInfoAttributesVersion2ValueData.keys())

fontInfoAttributesVersion3ValueData = deepcopy(fontInfoAttributesVersion2ValueData)
fontInfoAttributesVersion3ValueData.update({
	"versionMinor"							: dict(type=int, valueValidator=genericNonNegativeIntValidator),
	"unitsPerEm"							: dict(type=(int, float), valueValidator=genericNonNegativeNumberValidator),
	"openTypeHeadLowestRecPPEM"				: dict(type=int, valueValidator=genericNonNegativeNumberValidator),
	"openTypeHheaAscender"					: dict(type=int),
	"openTypeHheaDescender"					: dict(type=int),
	"openTypeHheaLineGap"					: dict(type=int),
	"openTypeHheaCaretOffset"				: dict(type=int),
	"openTypeOS2Panose"						: dict(type="integerList", valueValidator=fontInfoVersion3OpenTypeOS2PanoseValidator),
	"openTypeOS2TypoAscender"				: dict(type=int),
	"openTypeOS2TypoDescender"				: dict(type=int),
	"openTypeOS2TypoLineGap"				: dict(type=int),
	"openTypeOS2WinAscent"					: dict(type=int, valueValidator=genericNonNegativeNumberValidator),
	"openTypeOS2WinDescent"					: dict(type=int, valueValidator=genericNonNegativeNumberValidator),
	"openTypeOS2SubscriptXSize"				: dict(type=int),
	"openTypeOS2SubscriptYSize"				: dict(type=int),
	"openTypeOS2SubscriptXOffset"			: dict(type=int),
	"openTypeOS2SubscriptYOffset"			: dict(type=int),
	"openTypeOS2SuperscriptXSize"			: dict(type=int),
	"openTypeOS2SuperscriptYSize"			: dict(type=int),
	"openTypeOS2SuperscriptXOffset"			: dict(type=int),
	"openTypeOS2SuperscriptYOffset"			: dict(type=int),
	"openTypeOS2StrikeoutSize"				: dict(type=int),
	"openTypeOS2StrikeoutPosition"			: dict(type=int),
	"openTypeGaspRangeRecords"				: dict(type="dictList", valueValidator=fontInfoOpenTypeGaspRangeRecordsValidator),
	"openTypeNameRecords"					: dict(type="dictList", valueValidator=fontInfoOpenTypeNameRecordsValidator),
	"openTypeVheaVertTypoAscender"			: dict(type=int),
	"openTypeVheaVertTypoDescender"			: dict(type=int),
	"openTypeVheaVertTypoLineGap"			: dict(type=int),
	"openTypeVheaCaretOffset"				: dict(type=int),
	"woffMajorVersion"						: dict(type=int, valueValidator=genericNonNegativeIntValidator),
	"woffMinorVersion"						: dict(type=int, valueValidator=genericNonNegativeIntValidator),
	"woffMetadataUniqueID"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataUniqueIDValidator),
	"woffMetadataVendor"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataVendorValidator),
	"woffMetadataCredits"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataCreditsValidator),
	"woffMetadataDescription"				: dict(type=dict, valueValidator=fontInfoWOFFMetadataDescriptionValidator),
	"woffMetadataLicense"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataLicenseValidator),
	"woffMetadataCopyright"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataCopyrightValidator),
	"woffMetadataTrademark"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataTrademarkValidator),
	"woffMetadataLicensee"					: dict(type=dict, valueValidator=fontInfoWOFFMetadataLicenseeValidator),
	"woffMetadataExtensions"				: dict(type=list, valueValidator=fontInfoWOFFMetadataExtensionsValidator),
	"guidelines"							: dict(type=list, valueValidator=guidelinesValidator)
})
fontInfoAttributesVersion3 = set(fontInfoAttributesVersion3ValueData.keys())

# insert the type validator for all attrs that
# have no defined validator.
for attr, dataDict in list(fontInfoAttributesVersion2ValueData.items()):
	if "valueValidator" not in dataDict:
		dataDict["valueValidator"] = genericTypeValidator

for attr, dataDict in list(fontInfoAttributesVersion3ValueData.items()):
	if "valueValidator" not in dataDict:
		dataDict["valueValidator"] = genericTypeValidator

# Version Conversion Support
# These are used from converting from version 1
# to version 2 or vice-versa.

def _flipDict(d):
	flipped = {}
	for key, value in list(d.items()):
		flipped[value] = key
	return flipped

fontInfoAttributesVersion1To2 = {
	"menuName"		: "styleMapFamilyName",
	"designer"		: "openTypeNameDesigner",
	"designerURL"	: "openTypeNameDesignerURL",
	"createdBy"		: "openTypeNameManufacturer",
	"vendorURL"		: "openTypeNameManufacturerURL",
	"license"		: "openTypeNameLicense",
	"licenseURL"	: "openTypeNameLicenseURL",
	"ttVersion"		: "openTypeNameVersion",
	"ttUniqueID"	: "openTypeNameUniqueID",
	"notice"		: "openTypeNameDescription",
	"otFamilyName"	: "openTypeNamePreferredFamilyName",
	"otStyleName"	: "openTypeNamePreferredSubfamilyName",
	"otMacName"		: "openTypeNameCompatibleFullName",
	"weightName"	: "postscriptWeightName",
	"weightValue"	: "openTypeOS2WeightClass",
	"ttVendor"		: "openTypeOS2VendorID",
	"uniqueID"		: "postscriptUniqueID",
	"fontName"		: "postscriptFontName",
	"fondID"		: "macintoshFONDFamilyID",
	"fondName"		: "macintoshFONDName",
	"defaultWidth"	: "postscriptDefaultWidthX",
	"slantAngle"	: "postscriptSlantAngle",
	"fullName"		: "postscriptFullName",
	# require special value conversion
	"fontStyle"		: "styleMapStyleName",
	"widthName"		: "openTypeOS2WidthClass",
	"msCharSet"		: "postscriptWindowsCharacterSet"
}
fontInfoAttributesVersion2To1 = _flipDict(fontInfoAttributesVersion1To2)
deprecatedFontInfoAttributesVersion2 = set(fontInfoAttributesVersion1To2.keys())

_fontStyle1To2 = {
	64 : "regular",
	1  : "italic",
	32 : "bold",
	33 : "bold italic"
}
_fontStyle2To1 = _flipDict(_fontStyle1To2)
# Some UFO 1 files have 0
_fontStyle1To2[0] = "regular"

_widthName1To2 = {
	"Ultra-condensed" : 1,
	"Extra-condensed" : 2,
	"Condensed"		  : 3,
	"Semi-condensed"  : 4,
	"Medium (normal)" : 5,
	"Semi-expanded"	  : 6,
	"Expanded"		  : 7,
	"Extra-expanded"  : 8,
	"Ultra-expanded"  : 9
}
_widthName2To1 = _flipDict(_widthName1To2)
# FontLab's default width value is "Normal".
# Many format version 1 UFOs will have this.
_widthName1To2["Normal"] = 5
# FontLab has an "All" width value. In UFO 1
# move this up to "Normal".
_widthName1To2["All"] = 5
# "medium" appears in a lot of UFO 1 files.
_widthName1To2["medium"] = 5
# "Medium" appears in a lot of UFO 1 files.
_widthName1To2["Medium"] = 5

_msCharSet1To2 = {
	0	: 1,
	1	: 2,
	2	: 3,
	77	: 4,
	128 : 5,
	129 : 6,
	130 : 7,
	134 : 8,
	136 : 9,
	161 : 10,
	162 : 11,
	163 : 12,
	177 : 13,
	178 : 14,
	186 : 15,
	200 : 16,
	204 : 17,
	222 : 18,
	238 : 19,
	255 : 20
}
_msCharSet2To1 = _flipDict(_msCharSet1To2)

# 1 <-> 2

def convertFontInfoValueForAttributeFromVersion1ToVersion2(attr, value):
	"""
	Convert value from version 1 to version 2 format.
	Returns the new attribute name and the converted value.
	If the value is None, None will be returned for the new value.
	"""
	# convert floats to ints if possible
	if isinstance(value, float):
		if int(value) == value:
			value = int(value)
	if value is not None:
		if attr == "fontStyle":
			v = _fontStyle1To2.get(value)
			if v is None:
				raise UFOLibError(f"Cannot convert value ({value!r}) for attribute {attr}.")
			value = v
		elif attr == "widthName":
			v = _widthName1To2.get(value)
			if v is None:
				raise UFOLibError(f"Cannot convert value ({value!r}) for attribute {attr}.")
			value = v
		elif attr == "msCharSet":
			v = _msCharSet1To2.get(value)
			if v is None:
				raise UFOLibError(f"Cannot convert value ({value!r}) for attribute {attr}.")
			value = v
	attr = fontInfoAttributesVersion1To2.get(attr, attr)
	return attr, value

def convertFontInfoValueForAttributeFromVersion2ToVersion1(attr, value):
	"""
	Convert value from version 2 to version 1 format.
	Returns the new attribute name and the converted value.
	If the value is None, None will be returned for the new value.
	"""
	if value is not None:
		if attr == "styleMapStyleName":
			value = _fontStyle2To1.get(value)
		elif attr == "openTypeOS2WidthClass":
			value = _widthName2To1.get(value)
		elif attr == "postscriptWindowsCharacterSet":
			value = _msCharSet2To1.get(value)
	attr = fontInfoAttributesVersion2To1.get(attr, attr)
	return attr, value

def _convertFontInfoDataVersion1ToVersion2(data):
	converted = {}
	for attr, value in list(data.items()):
		# FontLab gives -1 for the weightValue
		# for fonts wil no defined value. Many
		# format version 1 UFOs will have this.
		if attr == "weightValue" and value == -1:
			continue
		newAttr, newValue = convertFontInfoValueForAttributeFromVersion1ToVersion2(attr, value)
		# skip if the attribute is not part of version 2
		if newAttr not in fontInfoAttributesVersion2:
			continue
		# catch values that can't be converted
		if value is None:
			raise UFOLibError(f"Cannot convert value ({value!r}) for attribute {newAttr}.")
		# store
		converted[newAttr] = newValue
	return converted

def _convertFontInfoDataVersion2ToVersion1(data):
	converted = {}
	for attr, value in list(data.items()):
		newAttr, newValue = convertFontInfoValueForAttributeFromVersion2ToVersion1(attr, value)
		# only take attributes that are registered for version 1
		if newAttr not in fontInfoAttributesVersion1:
			continue
		# catch values that can't be converted
		if value is None:
			raise UFOLibError(f"Cannot convert value ({value!r}) for attribute {newAttr}.")
		# store
		converted[newAttr] = newValue
	return converted

# 2 <-> 3

_ufo2To3NonNegativeInt = {
	"versionMinor",
	"openTypeHeadLowestRecPPEM",
	"openTypeOS2WinAscent",
	"openTypeOS2WinDescent"
}
_ufo2To3NonNegativeIntOrFloat = {
	"unitsPerEm",
}
_ufo2To3FloatToInt = {
	"openTypeHeadLowestRecPPEM",
	"openTypeHheaAscender",
	"openTypeHheaDescender",
	"openTypeHheaLineGap",
	"openTypeHheaCaretOffset",
	"openTypeOS2TypoAscender",
	"openTypeOS2TypoDescender",
	"openTypeOS2TypoLineGap",
	"openTypeOS2WinAscent",
	"openTypeOS2WinDescent",
	"openTypeOS2SubscriptXSize",
	"openTypeOS2SubscriptYSize",
	"openTypeOS2SubscriptXOffset",
	"openTypeOS2SubscriptYOffset",
	"openTypeOS2SuperscriptXSize",
	"openTypeOS2SuperscriptYSize",
	"openTypeOS2SuperscriptXOffset",
	"openTypeOS2SuperscriptYOffset",
	"openTypeOS2StrikeoutSize",
	"openTypeOS2StrikeoutPosition",
	"openTypeVheaVertTypoAscender",
	"openTypeVheaVertTypoDescender",
	"openTypeVheaVertTypoLineGap",
	"openTypeVheaCaretOffset"
}

def convertFontInfoValueForAttributeFromVersion2ToVersion3(attr, value):
	"""
	Convert value from version 2 to version 3 format.
	Returns the new attribute name and the converted value.
	If the value is None, None will be returned for the new value.
	"""
	if attr in _ufo2To3FloatToInt:
		try:
			value = round(value)
		except (ValueError, TypeError):
			raise UFOLibError("Could not convert value for %s." % attr)
	if attr in _ufo2To3NonNegativeInt:
		try:
			value = int(abs(value))
		except (ValueError, TypeError):
			raise UFOLibError("Could not convert value for %s." % attr)
	elif attr in _ufo2To3NonNegativeIntOrFloat:
		try:
			v = float(abs(value))
		except (ValueError, TypeError):
			raise UFOLibError("Could not convert value for %s." % attr)
		if v == int(v):
			v = int(v)
		if v != value:
			value = v
	return attr, value

def convertFontInfoValueForAttributeFromVersion3ToVersion2(attr, value):
	"""
	Convert value from version 3 to version 2 format.
	Returns the new attribute name and the converted value.
	If the value is None, None will be returned for the new value.
	"""
	return attr, value

def _convertFontInfoDataVersion3ToVersion2(data):
	converted = {}
	for attr, value in list(data.items()):
		newAttr, newValue = convertFontInfoValueForAttributeFromVersion3ToVersion2(attr, value)
		if newAttr not in fontInfoAttributesVersion2:
			continue
		converted[newAttr] = newValue
	return converted

def _convertFontInfoDataVersion2ToVersion3(data):
	converted = {}
	for attr, value in list(data.items()):
		attr, value = convertFontInfoValueForAttributeFromVersion2ToVersion3(attr, value)
		converted[attr] = value
	return converted

if __name__ == "__main__":
	import doctest
	doctest.testmod()
