// Copyright (C) 2015-2026 The Neo Project.
//
// TokenTransferKey.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Extensions;
using Neo.IO;
using System.Buffers.Binary;

namespace Neo.Plugins.Trackers;

public class TokenTransferKey : ISerializable
{
    public UInt160 UserScriptHash { get; protected set; }
    public ulong TimestampMS { get; protected set; }
    public UInt160 AssetScriptHash { get; protected set; }
    public uint BlockXferNotificationIndex { get; protected set; }
    public TokenTransferKey() : this(UInt160.Zero, 0, UInt160.Zero, 0) { }

    public TokenTransferKey(UInt160 userScriptHash, ulong timestamp, UInt160 assetScriptHash, uint xferIndex)
    {
        ArgumentNullException.ThrowIfNull(userScriptHash, nameof(userScriptHash));
        ArgumentNullException.ThrowIfNull(assetScriptHash, nameof(assetScriptHash));

        UserScriptHash = userScriptHash;
        TimestampMS = timestamp;
        AssetScriptHash = assetScriptHash;
        BlockXferNotificationIndex = xferIndex;
    }
    public virtual void Serialize(BinaryWriter writer)
    {
        writer.Write(UserScriptHash);
        writer.Write(BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(TimestampMS) : TimestampMS);
        writer.Write(AssetScriptHash);
        writer.Write(BlockXferNotificationIndex);
    }

    public virtual void Deserialize(ref MemoryReader reader)
    {
        UserScriptHash = reader.ReadSerializable<UInt160>();
        TimestampMS = BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(reader.ReadUInt64()) : reader.ReadUInt64();
        AssetScriptHash = reader.ReadSerializable<UInt160>();
        BlockXferNotificationIndex = reader.ReadUInt32();
    }

    public virtual int Size =>
          UInt160.Length +    //UserScriptHash
          sizeof(ulong) +     //TimestampMS
          UInt160.Length +    //AssetScriptHash
          sizeof(uint);       //BlockXferNotificationIndex
}
