from fontTools.misc.py23 import bytesjoin, tostr
from io import BytesIO
import struct
from fontTools.misc import sstruct
from collections import OrderedDict
from collections.abc import MutableMapping


class ResourceError(Exception):
	pass


class ResourceReader(MutableMapping):
	"""Reader for Mac OS resource forks.

	Parses a resource fork and returns resources according to their type.
	If run on OS X, this will open the resource fork in the filesystem.
	Otherwise, it will open the file itself and attempt to read it as
	though it were a resource fork.

	The returned object can be indexed by type and iterated over,
	returning in each case a list of py:class:`Resource` objects
	representing all the resources of a certain type.

	"""
	def __init__(self, fileOrPath):
		"""Open a file

		Args:
			fileOrPath: Either an object supporting a ``read`` method, an
				``os.PathLike`` object, or a string.
		"""
		self._resources = OrderedDict()
		if hasattr(fileOrPath, 'read'):
			self.file = fileOrPath
		else:
			try:
				# try reading from the resource fork (only works on OS X)
				self.file = self.openResourceFork(fileOrPath)
				self._readFile()
				return
			except (ResourceError, IOError):
				# if it fails, use the data fork
				self.file = self.openDataFork(fileOrPath)
		self._readFile()

	@staticmethod
	def openResourceFork(path):
		if hasattr(path, "__fspath__"):  # support os.PathLike objects
			path = path.__fspath__()
		with open(path + '/..namedfork/rsrc', 'rb') as resfork:
			data = resfork.read()
		infile = BytesIO(data)
		infile.name = path
		return infile

	@staticmethod
	def openDataFork(path):
		with open(path, 'rb') as datafork:
			data = datafork.read()
		infile = BytesIO(data)
		infile.name = path
		return infile

	def _readFile(self):
		self._readHeaderAndMap()
		self._readTypeList()

	def _read(self, numBytes, offset=None):
		if offset is not None:
			try:
				self.file.seek(offset)
			except OverflowError:
				raise ResourceError("Failed to seek offset ('offset' is too large)")
			if self.file.tell() != offset:
				raise ResourceError('Failed to seek offset (reached EOF)')
		try:
			data = self.file.read(numBytes)
		except OverflowError:
			raise ResourceError("Cannot read resource ('numBytes' is too large)")
		if len(data) != numBytes:
			raise ResourceError('Cannot read resource (not enough data)')
		return data

	def _readHeaderAndMap(self):
		self.file.seek(0)
		headerData = self._read(ResourceForkHeaderSize)
		sstruct.unpack(ResourceForkHeader, headerData, self)
		# seek to resource map, skip reserved
		mapOffset = self.mapOffset + 22
		resourceMapData = self._read(ResourceMapHeaderSize, mapOffset)
		sstruct.unpack(ResourceMapHeader, resourceMapData, self)
		self.absTypeListOffset = self.mapOffset + self.typeListOffset
		self.absNameListOffset = self.mapOffset + self.nameListOffset

	def _readTypeList(self):
		absTypeListOffset = self.absTypeListOffset
		numTypesData = self._read(2, absTypeListOffset)
		self.numTypes, = struct.unpack('>H', numTypesData)
		absTypeListOffset2 = absTypeListOffset + 2
		for i in range(self.numTypes + 1):
			resTypeItemOffset = absTypeListOffset2 + ResourceTypeItemSize * i
			resTypeItemData = self._read(ResourceTypeItemSize, resTypeItemOffset)
			item = sstruct.unpack(ResourceTypeItem, resTypeItemData)
			resType = tostr(item['type'], encoding='mac-roman')
			refListOffset = absTypeListOffset + item['refListOffset']
			numRes = item['numRes'] + 1
			resources = self._readReferenceList(resType, refListOffset, numRes)
			self._resources[resType] = resources

	def _readReferenceList(self, resType, refListOffset, numRes):
		resources = []
		for i in range(numRes):
			refOffset = refListOffset + ResourceRefItemSize * i
			refData = self._read(ResourceRefItemSize, refOffset)
			res = Resource(resType)
			res.decompile(refData, self)
			resources.append(res)
		return resources

	def __getitem__(self, resType):
		return self._resources[resType]

	def __delitem__(self, resType):
		del self._resources[resType]

	def __setitem__(self, resType, resources):
		self._resources[resType] = resources

	def __len__(self):
		return len(self._resources)

	def __iter__(self):
		return iter(self._resources)

	def keys(self):
		return self._resources.keys()

	@property
	def types(self):
		"""A list of the types of resources in the resource fork."""
		return list(self._resources.keys())

	def countResources(self, resType):
		"""Return the number of resources of a given type."""
		try:
			return len(self[resType])
		except KeyError:
			return 0

	def getIndices(self, resType):
		"""Returns a list of indices of resources of a given type."""
		numRes = self.countResources(resType)
		if numRes:
			return list(range(1, numRes+1))
		else:
			return []

	def getNames(self, resType):
		"""Return list of names of all resources of a given type."""
		return [res.name for res in self.get(resType, []) if res.name is not None]

	def getIndResource(self, resType, index):
		"""Return resource of given type located at an index ranging from 1
		to the number of resources for that type, or None if not found.
		"""
		if index < 1:
			return None
		try:
			res = self[resType][index-1]
		except (KeyError, IndexError):
			return None
		return res

	def getNamedResource(self, resType, name):
		"""Return the named resource of given type, else return None."""
		name = tostr(name, encoding='mac-roman')
		for res in self.get(resType, []):
			if res.name == name:
				return res
		return None

	def close(self):
		if not self.file.closed:
			self.file.close()


class Resource(object):
	"""Represents a resource stored within a resource fork.

	Attributes:
		type: resource type.
		data: resource data.
		id: ID.
		name: resource name.
		attr: attributes.
	"""

	def __init__(self, resType=None, resData=None, resID=None, resName=None,
			     resAttr=None):
		self.type = resType
		self.data = resData
		self.id = resID
		self.name = resName
		self.attr = resAttr

	def decompile(self, refData, reader):
		sstruct.unpack(ResourceRefItem, refData, self)
		# interpret 3-byte dataOffset as (padded) ULONG to unpack it with struct
		self.dataOffset, = struct.unpack('>L', bytesjoin([b"\0", self.dataOffset]))
		absDataOffset = reader.dataOffset + self.dataOffset
		dataLength, = struct.unpack(">L", reader._read(4, absDataOffset))
		self.data = reader._read(dataLength)
		if self.nameOffset == -1:
			return
		absNameOffset = reader.absNameListOffset + self.nameOffset
		nameLength, = struct.unpack('B', reader._read(1, absNameOffset))
		name, = struct.unpack('>%ss' % nameLength, reader._read(nameLength))
		self.name = tostr(name, encoding='mac-roman')


ResourceForkHeader = """
		> # big endian
		dataOffset:     L
		mapOffset:      L
		dataLen:        L
		mapLen:         L
"""

ResourceForkHeaderSize = sstruct.calcsize(ResourceForkHeader)

ResourceMapHeader = """
		> # big endian
		attr:              H
		typeListOffset:    H
		nameListOffset:    H
"""

ResourceMapHeaderSize = sstruct.calcsize(ResourceMapHeader)

ResourceTypeItem = """
		> # big endian
		type:              4s
		numRes:            H
		refListOffset:     H
"""

ResourceTypeItemSize = sstruct.calcsize(ResourceTypeItem)

ResourceRefItem = """
		> # big endian
		id:                h
		nameOffset:        h
		attr:              B
		dataOffset:        3s
		reserved:          L
"""

ResourceRefItemSize = sstruct.calcsize(ResourceRefItem)
