using System;
using System.Threading;
using Renci.SshNet.Common;
namespace Renci.SshNet
{
    /// 
    /// Serves as base class for client implementations, provides common client functionality.
    /// 
    public abstract class BaseClient : IDisposable
    {
        private static readonly TimeSpan Infinite = new TimeSpan(0, 0, 0, 0, -1);
        /// 
        /// Holds value indicating whether the connection info is owned by this client.
        /// 
        private readonly bool _ownsConnectionInfo;
        private TimeSpan _keepAliveInterval;
        private Timer _keepAliveTimer;
        private ConnectionInfo _connectionInfo;
        /// 
        /// Gets current session.
        /// 
        protected Session Session { get; private set; }
        /// 
        /// Gets the connection info.
        /// 
        /// 
        /// The connection info.
        /// 
        /// The method was called after the client was disposed.
        public ConnectionInfo ConnectionInfo
        {
            get
            {
                CheckDisposed();
                return _connectionInfo;
            }
            private set
            {
                _connectionInfo = value;
            }
        }
        /// 
        /// Gets a value indicating whether this client is connected to the server.
        /// 
        /// 
        /// true if this client is connected; otherwise, false.
        /// 
        /// The method was called after the client was disposed.
        public bool IsConnected
        {
            get
            {
                CheckDisposed();
                return this.Session != null && this.Session.IsConnected;
            }
        }
        /// 
        /// Gets or sets the keep-alive interval.
        /// 
        /// 
        /// The keep-alive interval. Specify negative one (-1) milliseconds to disable the
        /// keep-alive. This is the default value.
        /// 
        /// The method was called after the client was disposed.
        public TimeSpan KeepAliveInterval
        {
            get
            {
                CheckDisposed();
                return this._keepAliveInterval;
            }
            set
            {
                CheckDisposed();
                if (value == _keepAliveInterval)
                    return;
                if (value == Infinite)
                {
                    // stop the timer when the value is -1 milliseconds
                    StopKeepAliveTimer();
                }
                else
                {
                    // change the due time and interval of the timer if has already
                    // been created (which means the client is connected)
                    // 
                    // if the client is not yet connected, then the timer will be
                    // created with the new interval when Connect() is invoked
                    if (_keepAliveTimer != null)
                        _keepAliveTimer.Change(value, value);
                }
                this._keepAliveInterval = value;
            }
        }
        /// 
        /// Occurs when an error occurred.
        /// 
        /// 
        ///