using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace YoseenSDKCS
{
    public static class XmlUtil
    {
        static Dictionary<Type, XmlSerializer> _serializerDic;

        static XmlUtil()
        {
            _serializerDic = new Dictionary<Type, XmlSerializer>();
        }

        private static XmlSerializer getSerializer(Type t)
        {
            XmlSerializer serializer = null;
            if (!_serializerDic.TryGetValue(t, out serializer))
            {
                serializer = new XmlSerializer(t);
                _serializerDic.Add(t, serializer);
            }
            return serializer;
        }

        public static string Serialize<T>(T t)
        {
            XmlSerializer xmlSerializer = getSerializer(typeof(T));
            //fix20210722, utf8
            using (StringWriter2 stringWriter = new StringWriter2(Encoding.UTF8))
            {
                using (var writer = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
                {
                    xmlSerializer.Serialize(writer, t);
                    return stringWriter.ToString();
                }
            }
        }
        public static T Deserialize<T>(string s)
        {
            XmlSerializer xmlSerializer = getSerializer(typeof(T));
            using (StringReader stringReader = new StringReader(s))
            {
                using (var writer = XmlReader.Create(stringReader))
                {
                    return (T)xmlSerializer.Deserialize(writer);
                }
            }
        }

        public static bool Serialize<T>(T t, string filename)
        {
            XmlSerializer xmlSerializer = getSerializer(typeof(T));
            try
            {
                using (StreamWriter streamWriter = new StreamWriter(filename, false, Encoding.UTF8))
                {
                    using (var writer = XmlWriter.Create(streamWriter, new XmlWriterSettings { Indent = true }))
                    {
                        xmlSerializer.Serialize(writer, t);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public static bool Deserialize<T>(string filename, ref T t)
        {
            XmlSerializer xmlSerializer = getSerializer(typeof(T));
            try
            {
                using (StreamReader streamReader = new StreamReader(filename, Encoding.UTF8))
                {
                    using (var reader = XmlReader.Create(streamReader))
                    {
                        t = (T)xmlSerializer.Deserialize(reader);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }


    }


    public sealed class StringWriter2 : StringWriter
    {
        private readonly Encoding encoding;

        public StringWriter2() { }

        public StringWriter2(Encoding encoding)
        {
            this.encoding = encoding;
        }

        public override Encoding Encoding
        {
            get { return encoding; }
        }
    }
}
