using System.Threading.Channels;
using InnovEnergy.Lib.Protocols.Modbus.Connections;
using InnovEnergy.Lib.Protocols.Modbus.Conversions;

namespace InnovEnergy.Lib.Protocols.Modbus.Clients;

using Coils = IReadOnlyList<Boolean>;

// TODO: ModbusClient = Framer(TCP/RTU) + Connection(Serial/TCP) + Encoder(binary/ascii) + quirk(+1/0)
//                                        Transport

public abstract class ModbusClient
{
    protected ModbusConnection Connection { get; }
    protected Byte             SlaveId    { get; }
    
    
    // TODO: add additional functions: coils...
    
    public abstract Coils           ReadDiscreteInputs  (UInt16 readAddress,  UInt16 nValues);
    public abstract ModbusRegisters ReadInputRegisters  (UInt16 readAddress,  UInt16 nValues);
    public abstract ModbusRegisters ReadHoldingRegisters(UInt16 readAddress,  UInt16 nValues);
    public abstract UInt16          WriteMultipleCoils  (UInt16 writeAddress, Coils coils);
    public abstract UInt16          WriteRegisters      (UInt16 writeAddress, IReadOnlyList<UInt16> values);
    public abstract ModbusRegisters ReadWriteRegisters  (UInt16 readAddress,  UInt16 nbToRead, 
                                                         UInt16 writeAddress, IReadOnlyList<UInt16> registersToWrite);
    
    public UInt16 WriteMultipleCoils(UInt16 writeAddress, params Boolean[] coils)
    {
        return WriteMultipleCoils(writeAddress, (IReadOnlyList<Boolean>)coils);
    }
    
    public UInt16 WriteRegisters(ModbusRegisters registers)
    {
        return WriteRegisters(registers.StartRegister, registers);
    }

    public UInt16 WriteRegisters(UInt16 writeAddress, params UInt16[] values)
    {
        return WriteRegisters(writeAddress, (IReadOnlyList<UInt16>)values);
    }
    
    
    protected ModbusClient(ModbusConnection connection, Byte slaveId)
    {
        Connection = connection;
        SlaveId    = slaveId;
    }

    public void CloseConnection() => Connection.Close();
}