using InnovEnergy.Lib.Channels.V2.Bak.Connections;

namespace InnovEnergy.Lib.Channels.V2.Bak;

public abstract class GenericChannel2<C, Rx, Tx> : IChannel<Rx, Tx>, IConnection
{
    private readonly IConnection<C> _Connection;

    protected GenericChannel2(IConnection<C> connection)
    {
        _Connection = connection;
    }

    Task<Rx> IChannel<Rx, Tx>.Read()
    {
        throw new NotImplementedException();
    }

    Task IChannel<Rx, Tx>.Write(Tx tx)
    {
        throw new NotImplementedException();
    }

    public abstract Task<Rx> Read();
    public abstract Task Write(Tx tx);

    
    Task IConnection.Open() => _Connection.Open();

    public void Close()  => _Connection.Close();
    public Boolean IsOpen => _Connection.IsOpen;
}



public class GenericChannel<C, Rx, Tx> : IChannel<Rx, Tx>, IConnection
{
    private readonly Func<C, Task<Rx>> _Read;
    private readonly Func<C, Tx, Task> _Write;
    private readonly IConnection<C>    _Connection;
 
    public GenericChannel(IConnection<C> connection,
                       Func<C, Task<Rx>> read, 
                       Func<C, Tx, Task> write)
    {
        _Connection = connection;
        
        _Read  = read;
        _Write = write;
    }

    public async Task<Rx> Read()
    {
        try
        {
            var connection = await _Connection.Open();                
            return await _Read(connection);
        }
        catch 
        {
            _Connection.Close();
            throw;
        }
    }

    public async Task Write(Tx tx)
    {
        try
        {
            var connection = await _Connection.Open();
            await _Write(connection, tx);
        }
        catch
        {
            _Connection.Close();
            throw;
        }
    }

    public Task Open()  => _Connection.Open();
    public void Close() => _Connection.Close();

    public Boolean IsOpen => _Connection.IsOpen;

}