using Newtonsoft.Json;
using System;

namespace Combo
{
    [System.Serializable]
    public abstract class Serializable
    {
        public string ToJson()
        {
            try
            {
                return JsonConvert.SerializeObject(this);
            }
            catch (Exception _e)
            {
                throw new SerializationException(_e.Message, GetType().Name, "json");
            }
        }

        public static T FromJson<T>(string json) where T : Serializable
        {
            try
            {
                return JsonConvert.DeserializeObject<T>(json);
            }
            catch (Exception _e)
            {
                throw new SerializationException(_e.Message, json, typeof(T).Name);
            }

        }
    }

    public class SerializationException : JsonSerializationException
    {
        override public string Source { get; set; }
        public string Destination { get; }

        public SerializationException(string message, string source, string destination)
            : base(message)
        {
            Source = source;
            Destination = destination;
        }

        public SerializationException(string message, string source, string destination, Exception innerException)
            : base(message, innerException)
        {
            Source = source;
            Destination = destination;
        }

        public override string ToString()
        {
            return $"SerializationException: {Message}\nSource: {Source}\nDestination Type: {Destination}\n{StackTrace}";
        }
    }
}
