using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

namespace Siger.Middlelayer.Common.Helpers
{
    /// <summary>
    /// This is a utilities class for json serializer and deserializer.
    /// </summary>
    public class JsonHelper
    {
        /// <summary>
        /// Deserializer from json result.
        /// </summary>
        /// <typeparam name="T">Type of object.</typeparam>
        /// <param name="jsonResult">Json string</param>
        /// <returns>Instance of T.</returns>
        public static T DeserializerJsonResult<T>(string jsonResult)
        {
            if (!string.IsNullOrEmpty(jsonResult))
            {
                using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonResult)))
                {
                    var type = typeof(T);
                    var knownTypes = type.Assembly.GetTypes().Where(t =>
                        !t.IsAbstract && t.IsClass && t.GetCustomAttributes(typeof(DataContractAttribute)).Any());
                    var serializer = new DataContractJsonSerializer(type, knownTypes);
                    return (T)serializer.ReadObject(ms);
                }
            }

            return default(T);
        }

        /// <summary>
        /// Serialize from instance to json string
        /// </summary>
        /// <typeparam name="T">Type of object.</typeparam>
        /// <param name="instance">Instance need to serialize.</param>
        /// <returns>The json string</returns>
        public static string SerializerToJsonString<T>(T instance)
        {
            var type = instance.GetType();
            var knownTypes = type.Assembly.GetTypes().Where(t =>
                !t.IsAbstract && t.IsClass && t.GetCustomAttributes(typeof(DataContractAttribute)).Any());
            DataContractJsonSerializer json = new DataContractJsonSerializer(type, knownTypes);
            using (MemoryStream stream = new MemoryStream())
            {
                json.WriteObject(stream, instance);
                return Encoding.UTF8.GetString(stream.ToArray());
                //return JsonFormatter.FormatJson(szJson);
            }
        }
    }
}
