// Created with MonoDevelop
//
//    Copyright (C) 2024 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.



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

namespace Hiperscan.Common
{
    public static class DataSerializer
    {
        public static void Write<T>(T data, string fname, bool xml = true)
        {
            using (Stream stream = new FileStream(fname, FileMode.Create, FileAccess.Write))
            {
                DataSerializer.Write<T>(data, stream, xml);
            }
        }

        public static void Write<T>(T data, Stream stream, bool xml = true)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T));


            if (xml == true)
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = System.Text.Encoding.UTF8;
                settings.Indent = true;
                settings.IndentChars = "    ";
                settings.NewLineChars = "\n";

                using (XmlWriter writer = XmlWriter.Create(stream, settings))
                {
                    serializer.WriteStartObject(writer, data);
                    writer.WriteAttributeString("xmlns", "p", null, "http://schemas.microsoft.com/2003/10/Serialization/Arrays");
                    writer.WriteAttributeString("xmlns", "q", null, "http://www.w3.org/2001/XMLSchema");
                    serializer.WriteObjectContent(writer, data);
                    serializer.WriteEndObject(writer);
                }
            }
            else
            {
                using (var writer = XmlDictionaryWriter.CreateBinaryWriter(stream))
                {
                    serializer.WriteObject(writer, data);
                }
            }
        }

        public static T Read<T>(string fname, bool xml = true)
        {
            using (Stream stream = new FileStream(fname, FileMode.Open, FileAccess.Read))
            {
                return DataSerializer.Read<T>(stream, xml);
            }
        }

        public static T Read<T>(Stream stream, bool xml = true)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(T));

            if (xml)
            {
                using (XmlReader reader = XmlReader.Create(stream))
                {
                    return (T)serializer.ReadObject(reader, true);
                }
            }
            else
            {
                using (var reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
                {
                    return (T)serializer.ReadObject(reader);
                }
            }
        }
    }
}
