using IpcLibrary.Core;
using IpcLibrary.Core.Exceptions;
using IPCLibrary.Serialization;

namespace IpcLibrary.Serialization {
    /// <summary>
    /// 复合序列化器 - 根据数据类型选择最适合的序列化方式
    /// </summary>
    public class CompositeMessageSerializer : IMessageSerializer {
        private readonly JsonMessageSerializer _jsonSerializer;
        private readonly BinaryMessageSerializer _binarySerializer;

        public CompositeMessageSerializer() {
            _jsonSerializer = new JsonMessageSerializer();
            _binarySerializer = new BinaryMessageSerializer();
        }

        public byte[] Serialize(object obj) {
            if (obj == null)
                return new byte[0];

            // 对于简单类型和已知类型使用JSON，复杂类型使用二进制
            if (IsJsonSerializable(obj.GetType())) {
                var jsonData = _jsonSerializer.Serialize(obj);
                var result = new byte[jsonData.Length + 1];
                result[0] = 1; // JSON标识
                Array.Copy(jsonData, 0, result, 1, jsonData.Length);
                return result;
            } else {
                var binaryData = _binarySerializer.Serialize(obj);
                var result = new byte[binaryData.Length + 1];
                result[0] = 2; // Binary标识
                Array.Copy(binaryData, 0, result, 1, binaryData.Length);
                return result;
            }
        }

        public T Deserialize<T>(byte[] data) {
            if (data.Length == 0)
                return default(T);

            var serializationType = data[0];
            var actualData = new byte[data.Length - 1];
            Array.Copy(data, 1, actualData, 0, actualData.Length);

            switch (serializationType) {
                case 1: // JSON
                    return _jsonSerializer.Deserialize<T>(actualData);
                case 2: // Binary
                    return _binarySerializer.Deserialize<T>(actualData);
                default:
                    throw new IPCException($"未知的序列化类型: {serializationType}");
            }
        }

        public object Deserialize(byte[] data, Type type) {
            if (data.Length == 0)
                return null;

            var serializationType = data[0];
            var actualData = new byte[data.Length - 1];
            Array.Copy(data, 1, actualData, 0, actualData.Length);

            switch (serializationType) {
                case 1: // JSON
                    return _jsonSerializer.Deserialize(actualData, type);
                case 2: // Binary
                    return _binarySerializer.Deserialize(actualData, type);
                default:
                    throw new IPCException($"未知的序列化类型: {serializationType}");
            }
        }

        private bool IsJsonSerializable(Type type) {
            // 基本类型
            if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type == typeof(Guid))
                return true;

            // 数组
            if (type.IsArray && IsJsonSerializable(type.GetElementType()))
                return true;

            // 已知的IPC消息类型
            if (typeof(IPCMessage).IsAssignableFrom(type) ||
                typeof(MethodCallRequest).IsAssignableFrom(type) ||
                typeof(MethodCallResponse).IsAssignableFrom(type))
                return true;

            // 其他情况使用二进制序列化
            return false;
        }
    }
}
