using ThingsGateway.NewLife.Data;
using ThingsGateway.NewLife.Messaging;
using ThingsGateway.NewLife.Model;
using ThingsGateway.NewLife.Reflection;
using ThingsGateway.NewLife.Serialization;

namespace ThingsGateway.NewLife.Net.Handlers;

/// <summary>Json编码器。用于把用户对象编码为Json字符串</summary>
public class JsonCodec : Handler
{
    #region 属性
    /// <summary>Json序列化主机</summary>
    public IJsonHost JsonHost { get; set; } = JsonHelper.Default;
    #endregion

    /// <summary>发送消息时，写入数据，编码并加入队列</summary>
    /// <remarks>
    /// 遇到消息T时，调用Encode编码并加入队列。
    /// Encode返回空时，跳出调用链。
    /// </remarks>
    /// <param name="context"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public override Object? Write(IHandlerContext context, Object message)
    {
        var ext = context as IExtend;
        if (message.GetType().IsBaseType())
        {
            var str = message is DateTime dt ? dt.ToFullString() : message + string.Empty;
            message = str.GetBytes();

            // 通知标准网络封包使用的Flag
            if (ext != null) ext["Flag"] = DataKinds.String;
        }
        else if (message is not IPacket and not IMessage)
        {
            message = JsonHost.Write(message).GetBytes();

            // 通知标准网络封包使用的Flag
            if (ext != null) ext["Flag"] = DataKinds.Json;
        }

        if (message is Byte[] buf)
            message = new ArrayPacket(buf);

        return base.Write(context, message);
    }

    /// <summary>接收数据后，读取数据包，Decode解码得到消息</summary>
    /// <remarks>
    /// Decode可以返回多个消息，每个消息调用一次下一级处理器。
    /// Decode返回空时，跳出调用链。
    /// </remarks>
    /// <param name="context"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public override Object? Read(IHandlerContext context, Object message)
    {
        if (message is IPacket pk)
        {
            var str = pk.ToStr();
            if (!str.IsNullOrEmpty())
                message = JsonParser.Decode(str)!;
        }

        return base.Read(context, message);
    }
}
