using System;
using UnityEngine;
using XGame.Framework.FileSystem;

namespace XGame.Framework.Serialization
{
    public static class SerializationUtils
    {
        public static T Read<T>(string filePath) where T : class, ISerializable
        {
            try
            {
                var bytes = File.ReadAllBytes(filePath);
                if (bytes != null)
                {
                    EncryptXor(ref bytes, 1023);
                    var reader = new Reader(bytes);
                    var result = Activator.CreateInstance<T>();
                    result.Deserialize(reader);
                    return result;
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
            return default;
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bytes"></param>
        /// <param name="xorKey"></param>
        /// <returns></returns>
        public static T Read<T>(byte[] bytes, uint xorKey = 0) where T : class, ISerializable
        {
            try
            {
                if (bytes != null)
                {
                    if (xorKey != 0)
                    {
                        EncryptXor(ref bytes, xorKey);
                    }
                    var reader = new Reader(bytes);
                    var result = Activator.CreateInstance<T>();
                    result.Deserialize(reader);
                    return result;
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
            return default;
        }
        /// <summary>
        /// 异或加密
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="key">默认为 1023</param>
        public static void EncryptXor(ref byte[] bytes, uint key)
        {
            if (bytes == null)
                return;
            for (var i = 0; i < bytes.Length; i++) // 依次对字符串中各字符进行操作
            {
                var current = bytes[i];
                bytes[i] = (byte)(current ^ key); // 将密钥与字符异或
            }
        }
    }
}
