using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;

namespace MusicMetaTagger.Client.Tests
{
	public static class SerializationTester
	{
		private static void AssertFormatterSerializable(IFormatter formatter, object o)
		{
			var stream = new MemoryStream();

			try
			{
				formatter.Serialize(stream, o);
			}
			catch (Exception ex)
			{
				throw (new NotSupportedException("The object failed serialization.", ex));
			}

			stream.Seek(0, SeekOrigin.Begin);

			object temp;

			try
			{
				temp = formatter.Deserialize(stream);
			}
			catch (Exception ex)
			{
				throw (new NotSupportedException("The object failed deserialization.", ex));
			}

			EqualityTester.AssertEqual(o, temp);
		}

		public static void AssertBinarySerializable(object o)
		{
			var formatter = new BinaryFormatter();

			try
			{
				AssertFormatterSerializable(formatter, o);
			}
			catch (NotSupportedException ex)
			{
				throw (new NotSupportedException("The object failed binary serialization or deserialization.", ex));
			}
		}

		public static void AssertXmlSerializable(object o)
		{
			var t = o.GetType();

			var serializer = new XmlSerializer(t);

			var stream = new MemoryStream();

			try
			{
				serializer.Serialize(stream, o);
			}
			catch (Exception ex)
			{
				throw (new NotSupportedException("The object failed XML serialization.", ex));
			}

			stream.Seek(0, SeekOrigin.Begin);

			object temp;

			try
			{
				temp = serializer.Deserialize(stream);
			}
			catch (Exception ex)
			{
				throw (new NotSupportedException("The object failed XML deserialization.", ex));
			}

			EqualityTester.AssertEqual(o, temp);
		}

		public static void AssertSerializable(object o)
		{
			AssertBinarySerializable(o);
			AssertXmlSerializable(o);
		}
	}
}