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)


# python 3.11 doesn't like when a mixin overrides a dunder method like __str__
# for some reasons it keep using Enum.__str__, see
# https://github.com/fonttools/fonttools/pull/2655
UFOFormatVersion.__str__ = _VersionTupleEnumMixin.__str__


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()
