namespace RobotNet.Script;

/// <summary>
/// Quản ký kết nối Modbus TCP tới 1 thiết bị.
/// </summary>
public interface IModbusTcpClient : IAsyncDisposable, IDisposable
{
    /// <summary>
    /// Trạng thái kết nối hiện tại với thiết bị Modbus TCP.
    /// </summary>
    bool IsConnected { get; }

    /// <summary>
    /// Đọc các đầu vào rời rạc (Discrete Inputs) từ thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="quantity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<bool[]> ReadDiscreteInputsAsync(UInt16 startingAddress, UInt16 quantity, CancellationToken cancellationToken = default);

    /// <summary>
    /// Đọc các cuộn dây (Coils) từ thiết bị Modbus TCP.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="quantity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<bool[]> ReadCoilsAsync(UInt16 startingAddress, UInt16 quantity, CancellationToken cancellationToken = default);

    /// <summary>
    /// Đọc các thanh ghi giữ (Holding Registers) từ thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="quantity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<ushort[]> ReadHoldingRegistersAsync(UInt16 startingAddress, UInt16 quantity, CancellationToken cancellationToken = default);

    /// <summary>
    /// Đọc các thanh ghi đầu vào (Input Registers) từ thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="quantity"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<ushort[]> ReadInputRegistersAsync(UInt16 startingAddress, UInt16 quantity, CancellationToken cancellationToken = default);

    /// <summary>
    /// Ghi viết một cuộn dây (Coil) đơn lẻ đến thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="value"></param>
    /// <param name="cancellationToken"></param>
    Task WriteSingleCoilAsync(UInt16 startingAddress, bool value, CancellationToken cancellationToken = default);

    /// <summary>
    /// Ghi viết một thanh ghi đơn lẻ đến thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="value"></param>
    /// <param name="cancellationToken"></param>
    Task WriteSingleRegisterAsync(UInt16 startingAddress, UInt16 value, CancellationToken cancellationToken = default);

    /// <summary>
    /// Ghi viết nhiều cuộn dây (Coils) đến thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="values"></param>
    /// <param name="cancellationToken"></param>
    Task WriteMultipleCoilsAsync(UInt16 startingAddress, bool[] values, CancellationToken cancellationToken = default);

    /// <summary>
    /// Ghi viết nhiều thanh ghi (Holding Registers) đến thiết bị Modbus TCP với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="startingAddress"></param>
    /// <param name="values"></param>
    /// <param name="cancellationToken"></param>
    Task WriteMultipleRegistersAsync(UInt16 startingAddress, UInt16[] values, CancellationToken cancellationToken = default);

    /// <summary>
    /// Đọc và ghi viết nhiều thanh ghi (Holding Registers) trong một lần gọi với hỗ trợ hủy bỏ.
    /// </summary>
    /// <param name="readStart"></param>
    /// <param name="readCount"></param>
    /// <param name="writeStart"></param>
    /// <param name="writeValues"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<ushort[]> ReadWriteMultipleRegistersAsync(ushort readStart, ushort readCount, ushort writeStart, IReadOnlyList<ushort> writeValues, CancellationToken cancellationToken = default);
}

