using System;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using Renci.SshNet.Channels;
using Renci.SshNet.Common;
using Renci.SshNet.Messages;
using Renci.SshNet.Messages.Authentication;
using Renci.SshNet.Messages.Connection;
namespace Renci.SshNet
{
    /// 
    /// Provides functionality to connect and interact with SSH server.
    /// 
    internal interface ISession : IDisposable
    {
        /// 
        /// Gets or sets the connection info.
        /// 
        /// The connection info.
        IConnectionInfo ConnectionInfo { get; }
        /// 
        /// Gets a value indicating whether the session is connected.
        /// 
        /// 
        /// true if the session is connected; otherwise, false.
        /// 
        bool IsConnected { get; }
        /// 
        /// Gets the session semaphore that controls session channels.
        /// 
        /// 
        /// The session semaphore.
        /// 
        SemaphoreLight SessionSemaphore { get; }
        /// 
        /// Gets a  that can be used to wait for the message listener loop to complete.
        /// 
        /// 
        /// A  that can be used to wait for the message listener loop to complete, or
        /// null when the session has not been connected.
        /// 
        WaitHandle MessageListenerCompleted { get; }
        /// 
        /// Connects to the server.
        /// 
        /// Socket connection to the SSH server or proxy server could not be established, or an error occurred while resolving the hostname.
        /// SSH session could not be established.
        /// Authentication of SSH session failed.
        /// Failed to establish proxy connection.
        void Connect();
        /// 
        /// Asynchronously connects to the server.
        /// 
        /// The  to observe.
        /// A  that represents the asynchronous connect operation.
        /// Socket connection to the SSH server or proxy server could not be established, or an error occurred while resolving the hostname.
        /// SSH session could not be established.
        /// Authentication of SSH session failed.
        /// Failed to establish proxy connection.
        Task ConnectAsync(CancellationToken cancellationToken);
        /// 
        /// Create a new SSH session channel.
        /// 
        /// 
        /// A new SSH session channel.
        /// 
        IChannelSession CreateChannelSession();
        /// 
        /// Create a new channel for a locally forwarded TCP/IP port.
        /// 
        /// 
        /// A new channel for a locally forwarded TCP/IP port.
        /// 
        IChannelDirectTcpip CreateChannelDirectTcpip();
        /// 
        /// Creates a "forwarded-tcpip" SSH channel.
        /// 
        /// 
        /// A new "forwarded-tcpip" SSH channel.
        /// 
        IChannelForwardedTcpip CreateChannelForwardedTcpip(uint remoteChannelNumber, uint remoteWindowSize, uint remoteChannelDataPacketSize);
        /// 
        /// Disconnects from the server.
        /// 
        /// 
        /// This sends a SSH_MSG_DISCONNECT message to the server, waits for the
        /// server to close the socket on its end and subsequently closes the client socket.
        /// 
        void Disconnect();
        /// 
        /// Called when client is disconnecting from the server.
        /// 
        void OnDisconnecting();
        /// 
        /// Registers SSH message with the session.
        /// 
        /// The name of the message to register with the session.
        void RegisterMessage(string messageName);
        /// 
        /// Sends a message to the server.
        /// 
        /// The message to send.
        /// The client is not connected.
        /// The operation timed out.
        /// The size of the packet exceeds the maximum size defined by the protocol.
        void SendMessage(Message message);
        /// 
        /// Sends a message to the server.
        /// 
        /// The message to send.
        /// 
        /// true if the message was sent to the server; otherwise, false.
        /// 
        /// The size of the packet exceeds the maximum size defined by the protocol.
        /// 
        /// This methods returns false when the attempt to send the message results in a
        ///  or a .
        /// 
        bool TrySendMessage(Message message);
        /// 
        /// Unregister SSH message from the session.
        /// 
        /// The name of the message to unregister with the session.
        void UnRegisterMessage(string messageName);
        /// 
        /// Waits for the specified handle or the exception handle for the receive thread
        /// to signal within the connection timeout.
        /// 
        /// The wait handle.
        /// A received package was invalid or failed the message integrity check.
        /// None of the handles are signaled in time and the session is not disconnecting.
        /// A socket error was signaled while receiving messages from the server.
        /// 
        /// When neither handles are signaled in time and the session is not closing, then the
        /// session is disconnected.
        /// 
        void WaitOnHandle(WaitHandle waitHandle);
        /// 
        /// Waits for the specified handle or the exception handle for the receive thread
        /// to signal within the specified timeout.
        /// 
        /// The wait handle.
        /// The time to wait for any of the handles to become signaled.
        /// A received package was invalid or failed the message integrity check.
        /// None of the handles are signaled in time and the session is not disconnecting.
        /// A socket error was signaled while receiving messages from the server.
        /// 
        /// When neither handles are signaled in time and the session is not closing, then the
        /// session is disconnected.
        /// 
        void WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout);
        /// 
        /// Waits for the specified  to receive a signal, using a 
        /// to specify the time interval.
        /// 
        /// The  that should be signaled.
        /// A  that represents the number of milliseconds to wait, or a  that represents -1 milliseconds to wait indefinitely.
        /// When this method returns , contains the .
        /// 
        /// A .
        /// 
        WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout, out Exception exception);
        /// 
        /// Waits for the specified  to receive a signal, using a 
        /// to specify the time interval.
        /// 
        /// The  that should be signaled.
        /// A  that represents the number of milliseconds to wait, or a  that represents -1 milliseconds to wait indefinitely.
        /// 
        /// A .
        /// 
        WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout);
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelCloseReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelDataReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelEofReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelExtendedDataReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelFailureReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelOpenConfirmationReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelOpenFailureReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelOpenReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelRequestReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelSuccessReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> ChannelWindowAdjustReceived;
        /// 
        /// Occurs when session has been disconnected from the server.
        /// 
        event EventHandler Disconnected;
        /// 
        /// Occurs when an error occurred.
        /// 
        event EventHandler ErrorOccured;
        /// 
        /// Occurs when host key received.
        /// 
        event EventHandler HostKeyReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> RequestSuccessReceived;
        /// 
        /// Occurs when  message received
        /// 
        event EventHandler> RequestFailureReceived;
        /// 
        /// Occurs when  message is received from the server.
        /// 
        event EventHandler> UserAuthenticationBannerReceived;
    }
}