using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Renci.SshNet.Common;
namespace Renci.SshNet
{
    /// 
    /// Provides connection information when password authentication method is used
    /// 
    public class PasswordConnectionInfo : ConnectionInfo, IDisposable
    {
        /// 
        /// Occurs when user's password has expired and needs to be changed.
        /// 
        public event EventHandler PasswordExpired;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        public PasswordConnectionInfo(string host, string username, string password)
            : this(host, 22, username, Encoding.UTF8.GetBytes(password))
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection port.
        /// Connection username.
        /// Connection password.
        ///  is null.
        ///  is invalid, or  is null or contains whitespace characters.
        ///  is not within  and .
        public PasswordConnectionInfo(string host, int port, string username, string password)
            : this(host, port, username, Encoding.UTF8.GetBytes(password), ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// The port.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort)
            : this(host, port, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// The port.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        public PasswordConnectionInfo(string host, int port, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
            : this(host, port, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort)
            : this(host, 22, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
            : this(host, 22, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        /// The proxy password.
        public PasswordConnectionInfo(string host, string username, string password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
            : this(host, 22, username, Encoding.UTF8.GetBytes(password), proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        public PasswordConnectionInfo(string host, string username, byte[] password)
            : this(host, 22, username, password)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection port.
        /// Connection username.
        /// Connection password.
        ///  is null.
        ///  is invalid, or  is null or contains whitespace characters.
        ///  is not within  and .
        public PasswordConnectionInfo(string host, int port, string username, byte[] password)
            : this(host, port, username, password, ProxyTypes.None, string.Empty, 0, string.Empty, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// The port.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort)
            : this(host, port, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// The port.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
            : this(host, port, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort)
            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, string.Empty, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername)
            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, string.Empty)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        /// The proxy password.
        public PasswordConnectionInfo(string host, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
            : this(host, 22, username, password, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword)
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Connection host.
        /// The port.
        /// Connection username.
        /// Connection password.
        /// Type of the proxy.
        /// The proxy host.
        /// The proxy port.
        /// The proxy username.
        /// The proxy password.
        public PasswordConnectionInfo(string host, int port, string username, byte[] password, ProxyTypes proxyType, string proxyHost, int proxyPort, string proxyUsername, string proxyPassword)
            : base(host, port, username, proxyType, proxyHost, proxyPort, proxyUsername, proxyPassword, new PasswordAuthenticationMethod(username, password))
        {
            foreach (var authenticationMethod in this.AuthenticationMethods.OfType())
            {
                authenticationMethod.PasswordExpired += AuthenticationMethod_PasswordExpired;
            }
        }
        private void AuthenticationMethod_PasswordExpired(object sender, AuthenticationPasswordChangeEventArgs e)
        {
            if (this.PasswordExpired != null)
            {
                this.PasswordExpired(sender, e);
            }
        }
        #region IDisposable Members
        private bool isDisposed = false;
        /// 
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// 
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        /// 
        /// Releases unmanaged and - optionally - managed resources
        /// 
        /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.isDisposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    if (this.AuthenticationMethods != null)
                    {
                        foreach (var authenticationMethods in this.AuthenticationMethods.OfType())
                        {
                            authenticationMethods.Dispose();
                        }
                    }
                }
                // Note disposing has been done.
                isDisposed = true;
            }
        }
        /// 
        /// Releases unmanaged resources and performs other cleanup operations before the
        ///  is reclaimed by garbage collection.
        /// 
        ~PasswordConnectionInfo()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }
        #endregion
    }
}