using System;
namespace Renci.SshNet.Messages.Connection
{
    /// 
    /// Represents SSH_MSG_GLOBAL_REQUEST message.
    /// 
    [Message("SSH_MSG_GLOBAL_REQUEST", 80)]
    public class GlobalRequestMessage : Message
    {
        /// 
        /// Gets the name of the request.
        /// 
        /// 
        /// The name of the request.
        /// 
        public GlobalRequestName RequestName { get; private set; }
        /// 
        /// Gets a value indicating whether message reply should be sent..
        /// 
        /// 
        ///   true if message reply should be sent; otherwise, false.
        /// 
        public bool WantReply { get; private set; }
        /// 
        /// Gets the address to bind to.
        /// 
        public string AddressToBind { get; private set; }
        //  TODO:   Extract AddressToBind property to be in different class and GlobalREquestMessage to be a base class fo it.
        /// 
        /// Gets port number to bind to.
        /// 
        public UInt32 PortToBind { get; private set; }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        public GlobalRequestMessage()
        {
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Name of the request.
        /// if set to true [want reply].
        public GlobalRequestMessage(GlobalRequestName requestName, bool wantReply)
        {
            this.RequestName = requestName;
            this.WantReply = wantReply;
        }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// Name of the request.
        /// if set to true [want reply].
        /// The address to bind.
        /// The port to bind.
        public GlobalRequestMessage(GlobalRequestName requestName, bool wantReply, string addressToBind, uint portToBind)
            : this(requestName, wantReply)
        {
            this.AddressToBind = addressToBind;
            this.PortToBind = portToBind;
        }
        /// 
        /// Called when type specific data need to be loaded.
        /// 
        protected override void LoadData()
        {
            var requestName = this.ReadAsciiString();
            switch (requestName)
            {
                case "tcpip-forward":
                    this.RequestName = GlobalRequestName.TcpIpForward;
                    break;
                case "cancel-tcpip-forward":
                    this.RequestName = GlobalRequestName.CancelTcpIpForward;
                    break;
                default:
                    break;
            }
            this.WantReply = this.ReadBoolean();
            this.AddressToBind = this.ReadString();
            this.PortToBind = this.ReadUInt32();
        }
        /// 
        /// Called when type specific data need to be saved.
        /// 
        protected override void SaveData()
        {
            switch (this.RequestName)
            {
                case GlobalRequestName.TcpIpForward:
                    this.WriteAscii("tcpip-forward");
                    break;
                case GlobalRequestName.CancelTcpIpForward:
                    this.WriteAscii("cancel-tcpip-forward");
                    break;
                default:
                    break;
            }
            this.Write(this.WantReply);
            switch (this.RequestName)
            {
                case GlobalRequestName.TcpIpForward:
                case GlobalRequestName.CancelTcpIpForward:
                    this.Write(this.AddressToBind);
                    this.Write(this.PortToBind);
                    break;
                default:
                    break;
            }
        }
    }
}