# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
import os
import shutil
import unittest
import tempfile
from io import open
from fontTools.ufoLib import UFOReader, UFOWriter, UFOLibError
from fontTools.ufoLib import plistlib
from .testSupport import fontInfoVersion1, fontInfoVersion2


class TestInfoObject(object): pass


class ReadFontInfoVersion1TestCase(unittest.TestCase):

	def setUp(self):
		self.dstDir = tempfile.mktemp()
		os.mkdir(self.dstDir)
		metaInfo = {
			"creator": "test",
			"formatVersion": 1
		}
		path = os.path.join(self.dstDir, "metainfo.plist")
		with open(path, "wb") as f:
			plistlib.dump(metaInfo, f)

	def tearDown(self):
		shutil.rmtree(self.dstDir)

	def _writeInfoToPlist(self, info):
		path = os.path.join(self.dstDir, "fontinfo.plist")
		with open(path, "wb") as f:
			plistlib.dump(info, f)

	def testRead(self):
		originalData = dict(fontInfoVersion1)
		self._writeInfoToPlist(originalData)
		infoObject = TestInfoObject()
		reader = UFOReader(self.dstDir, validate=True)
		reader.readInfo(infoObject)
		for attr in dir(infoObject):
			if attr not in fontInfoVersion2:
				continue
			originalValue = fontInfoVersion2[attr]
			readValue = getattr(infoObject, attr)
			self.assertEqual(originalValue, readValue)

	def testFontStyleConversion(self):
		fontStyle1To2 = {
			64 : "regular",
			1  : "italic",
			32 : "bold",
			33 : "bold italic"
		}
		for old, new in list(fontStyle1To2.items()):
			info = dict(fontInfoVersion1)
			info["fontStyle"] = old
			self._writeInfoToPlist(info)
			reader = UFOReader(self.dstDir, validate=True)
			infoObject = TestInfoObject()
			reader.readInfo(infoObject)
			self.assertEqual(new, infoObject.styleMapStyleName)

	def testWidthNameConversion(self):
		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
		}
		for old, new in list(widthName1To2.items()):
			info = dict(fontInfoVersion1)
			info["widthName"] = old
			self._writeInfoToPlist(info)
			reader = UFOReader(self.dstDir, validate=True)
			infoObject = TestInfoObject()
			reader.readInfo(infoObject)
			self.assertEqual(new, infoObject.openTypeOS2WidthClass)


class WriteFontInfoVersion1TestCase(unittest.TestCase):

	def setUp(self):
		self.tempDir = tempfile.mktemp()
		os.mkdir(self.tempDir)
		self.dstDir = os.path.join(self.tempDir, "test.ufo")

	def tearDown(self):
		shutil.rmtree(self.tempDir)

	def makeInfoObject(self):
		infoObject = TestInfoObject()
		for attr, value in list(fontInfoVersion2.items()):
			setattr(infoObject, attr, value)
		return infoObject

	def readPlist(self):
		path = os.path.join(self.dstDir, "fontinfo.plist")
		with open(path, "rb") as f:
			plist = plistlib.load(f)
		return plist

	def testWrite(self):
		infoObject = self.makeInfoObject()
		writer = UFOWriter(self.dstDir, formatVersion=1)
		writer.writeInfo(infoObject)
		writtenData = self.readPlist()
		for attr, originalValue in list(fontInfoVersion1.items()):
			newValue = writtenData[attr]
			self.assertEqual(newValue, originalValue)

	def testFontStyleConversion(self):
		fontStyle1To2 = {
			64 : "regular",
			1  : "italic",
			32 : "bold",
			33 : "bold italic"
		}
		for old, new in list(fontStyle1To2.items()):
			infoObject = self.makeInfoObject()
			infoObject.styleMapStyleName = new
			writer = UFOWriter(self.dstDir, formatVersion=1)
			writer.writeInfo(infoObject)
			writtenData = self.readPlist()
			self.assertEqual(writtenData["fontStyle"], old)

	def testWidthNameConversion(self):
		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
		}
		for old, new in list(widthName1To2.items()):
			infoObject = self.makeInfoObject()
			infoObject.openTypeOS2WidthClass = new
			writer = UFOWriter(self.dstDir, formatVersion=1)
			writer.writeInfo(infoObject)
			writtenData = self.readPlist()
			self.assertEqual(writtenData["widthName"], old)
