using Newtonsoft.Json;
using System;

namespace VCommon.Json
{
    public class VJsonSerializer : IVJsonSerializer
    {
        private readonly JsonSerializerSettings _settings; //TODO: 改用 JsonSerializer 实例节省每次创建开销

        public VJsonSerializer(JsonSerializerSettings settings) => _settings = settings;

        /// <summary> 反序列化: 如果传入json为null则返回T的默认值 </summary>
        public T DeserializeObject<T>(string json)
            => json == null
                ? default(T)
                : JsonConvert.DeserializeObject<T>(json, _settings);

        /// <summary> 反序列化匿名类型: 如果传入json为null则返回T的默认值 </summary>
        public T DeserializeAnonymousTypeObject<T>(string json, T anon = default(T))
            => json == null
                ? default(T)
                : JsonConvert.DeserializeAnonymousType(json, anon, _settings);

        /// <summary> 反序列化: 按指定类型, 如果传入的json为null则返回该类型的默认值 </summary>
        public object DeserializeObject(string json, Type type)
            => json == null
                ? (type.IsValueType ? Activator.CreateInstance(type) : null)
                : JsonConvert.DeserializeObject(json, type, _settings);

        /// <summary> 序列化 </summary>
        public string SerializeObject(object obj) => JsonConvert.SerializeObject(obj, _settings);

        //static shortcut

        private static readonly JsonSerializerSettings IgnoreNullSettings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
        };

        private static readonly JsonSerializerSettings IncludeNullSettings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Include,
        };

        public static readonly VJsonSerializer IgnoreNullSerializer = new VJsonSerializer(IgnoreNullSettings);
        public static readonly VJsonSerializer IncludeNullSerializer = new VJsonSerializer(IncludeNullSettings);
        public static readonly VJsonSerializer DefaultSerializer = IgnoreNullSerializer;

        /// <summary> 反序列化: 如果传入json为null则返回T的默认值 </summary>
        public static T Deserialize<T>(string json)
            => json == null
                ? default(T)
                : DefaultSerializer.DeserializeObject<T>(json);

        /// <summary> 反序列化匿名类型: 如果传入json为null则返回T的默认值 </summary>
        public T DeserializeAnonymousType<T>(string json, T anon = default(T))
            => json == null
                ? default(T)
                : DefaultSerializer.DeserializeAnonymousTypeObject(json, anon);

        /// <summary> 反序列化: 按指定类型, 如果传入的json为null则返回该类型的默认值 </summary>
        public static object Deserialize(string json, Type type)
            => json == null
                ? (type.IsValueType ? Activator.CreateInstance(type) : null)
                : DefaultSerializer.DeserializeObject(json, type);

        /// <summary> 序列化, 包括值为null的成员 </summary>
        public static string SerializeIncludeNull(object obj) => DefaultSerializer.SerializeObject(obj);

        /// <summary> 序列化, 忽略值为null的成员, 节省空间 </summary>
        public static string Serialize(object obj) => DefaultSerializer.SerializeObject(obj);
    }
}
