using System;
using Renci.SshNet.Common;
namespace Renci.SshNet
{
    /// 
    /// Base class for port forwarding functionality.
    /// 
    public abstract class ForwardedPort
    {
        /// 
        /// Gets or sets the session.
        /// 
        /// 
        /// The session.
        /// 
        internal Session Session { get; set; }
        /// 
        /// Gets or sets a value indicating whether port forwarding is started.
        /// 
        /// 
        /// true if port forwarding is started; otherwise, false.
        /// 
        public bool IsStarted { get; protected set; }
        /// 
        /// Occurs when an exception is thrown.
        /// 
        public event EventHandler Exception;
        /// 
        /// Occurs when a port forwarding request is received.
        /// 
        public event EventHandler RequestReceived;
        /// 
        /// Starts port forwarding.
        /// 
        public virtual void Start()
        {
            if (this.Session == null)
            {
                throw new InvalidOperationException("Forwarded port is not added to a client.");
            }
            if (!this.Session.IsConnected)
            {
                throw new SshConnectionException("Client not connected.");
            }
            this.Session.ErrorOccured += Session_ErrorOccured;
        }
        /// 
        /// Stops port forwarding.
        /// 
        public virtual void Stop()
        {
            if (this.Session != null)
            {
                this.Session.ErrorOccured -= Session_ErrorOccured;
            }
        }
        /// 
        /// Raises  event.
        /// 
        /// The exception.
        protected void RaiseExceptionEvent(Exception exception)
        {
            var handlers = Exception;
            if (handlers != null)
            {
                handlers(this, new ExceptionEventArgs(exception));
            }
        }
        /// 
        /// Raises  event.
        /// 
        /// Request originator host.
        /// Request originator port.
        protected void RaiseRequestReceived(string host, uint port)
        {
            var handlers = RequestReceived;
            if (handlers != null)
            {
                RequestReceived(this, new PortForwardEventArgs(host, port));
            }
        }
        /// 
        /// Handles session ErrorOccured event.
        /// 
        /// The source of the event.
        /// The  instance containing the event data.
        private void Session_ErrorOccured(object sender, ExceptionEventArgs e)
        {
            RaiseExceptionEvent(e.Exception);
        }
    }
}