//-----------------------------------------------------------------------
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//-----------------------------------------------------------------------
namespace System.IdentityModel.Protocols.WSTrust
{
    using System.Xml;
    /// 
    /// Class for serializing a WS-Trust 1.3 RequestSecurityTokenResponse to an XmlWriter
    /// 
    public class WSTrust13ResponseSerializer : WSTrustResponseSerializer
    {
        /// 
        /// Deserializes an RSTR and returns a RequestSecurityTokenRespone object.
        /// 
        /// Reader over the RSTR.
        /// Current Serialization context.
        /// RequestSecurityTokenResponse object if deserialization was successful.
        /// The given reader or context parameter is null
        public override RequestSecurityTokenResponse ReadXml(XmlReader reader, WSTrustSerializationContext context)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            bool isFinal = false;
            if (reader.IsStartElement(WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection, WSTrust13Constants.NamespaceURI))
            {
                reader.ReadStartElement(WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection, WSTrust13Constants.NamespaceURI);
                isFinal = true;
            }
            RequestSecurityTokenResponse rstr = WSTrustSerializationHelper.CreateResponse(reader, context, this, WSTrustConstantsAdapter.Trust13);
            rstr.IsFinal = isFinal;
            if (isFinal)
            {
                reader.ReadEndElement();
            }
            return rstr;
        }
        /// 
        /// Override of the base class that Reads a specific child element inside the RSTR.
        /// 
        /// Reader pointing at an element to read inside the RSTR.
        /// The RequestSecurityTokenResponse element that is being populated from the reader.
        /// Current Serialization context.
        /// Either reader or rstr or context parameter is null.
        /// Unable to deserialize the current parameter.
        public override void ReadXmlElement(XmlReader reader, RequestSecurityTokenResponse rstr, WSTrustSerializationContext context)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }
            if (rstr == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
            }
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            if (reader.IsStartElement(WSTrust13Constants.ElementNames.KeyWrapAlgorithm, WSTrust13Constants.NamespaceURI))
            {
                rstr.KeyWrapAlgorithm = reader.ReadElementContentAsString();
                return;
            }
            WSTrustSerializationHelper.ReadRSTRXml(reader, rstr, context, WSTrustConstantsAdapter.Trust13);
        }
        /// 
        /// Writes out the supported elements on the response object. 
        /// 
        /// The response instance
        /// The writer to write to
        /// Current Serialization context.
        /// Either rstr or writer or context parameter is null.
        public override void WriteKnownResponseElement(RequestSecurityTokenResponse rstr, XmlWriter writer, WSTrustSerializationContext context)
        {
            if (rstr == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
            }
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            // Write out the exisiting ones
            WSTrustSerializationHelper.WriteKnownResponseElement(rstr, writer, context, this, WSTrustConstantsAdapter.Trust13);
            // Specific to WS-Trust 13
            if (!string.IsNullOrEmpty(rstr.KeyWrapAlgorithm))
            {
                this.WriteXmlElement(writer, WSTrust13Constants.ElementNames.KeyWrapAlgorithm, rstr.KeyWrapAlgorithm, rstr, context);
            }
        }
        /// 
        /// Serializes a RequestSecurityTokenResponse object to the given XmlWriter
        /// stream.
        /// 
        /// RequestSecurityTokenResponse object that needs to be serialized to the writer.
        /// XmlWriter into which the object will be serialized
        /// Current Serialization context.
        /// The given response or writer or context parameter is null
        public override void WriteXml(RequestSecurityTokenResponse response, XmlWriter writer, WSTrustSerializationContext context)
        {
            if (response == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("response");
            }
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            if (response.IsFinal)
            {
                writer.WriteStartElement(WSTrust13Constants.Prefix, WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection, WSTrust13Constants.NamespaceURI);
            }
            WSTrustSerializationHelper.WriteResponse(response, writer, context, this, WSTrustConstantsAdapter.Trust13);
            if (response.IsFinal)
            {
                writer.WriteEndElement();
            }
        }
        /// 
        /// Override of the Base class method that writes a specific RSTR parameter to the outgoing stream.
        /// 
        /// Writer to which the RSTR is serialized
        /// The Local name of the element to be written.
        /// The value of the element.
        /// The entire RSTR object that is being serialized.
        /// Current Serialization context.
        /// Either writer or rstr or context is null.
        /// elementName is null or an empty string.
        public override void WriteXmlElement(XmlWriter writer, string elementName, object elementValue, RequestSecurityTokenResponse rstr, WSTrustSerializationContext context)
        {
            if (writer == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }
            if (string.IsNullOrEmpty(elementName))
            {
                throw DiagnosticUtility.ThrowHelperArgumentNullOrEmptyString("elementName");
            }
            if (rstr == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("rstr");
            }
            if (context == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
            }
            if (StringComparer.Ordinal.Equals(elementName, WSTrust13Constants.ElementNames.KeyWrapAlgorithm))
            {
                writer.WriteElementString(WSTrust13Constants.Prefix, WSTrust13Constants.ElementNames.KeyWrapAlgorithm, WSTrust13Constants.NamespaceURI, (string)elementValue);
                return;
            }
            WSTrustSerializationHelper.WriteRSTRXml(writer, elementName, elementValue, context, WSTrustConstantsAdapter.Trust13);
        }
        /// 
        /// Checks if the given reader is positioned at a RequestSecurityTokenResponse or 
        /// RequestSecurityTokenResponseCollection element with namespace 'http://docs.oasis-open.org/ws-sx/ws-trust/200512'
        /// 
        /// The reader to read from
        /// 
        /// 'True' if the reader is positioned at a RequestSecurityTokenResponse or RequestSecurityTokenResponseCollection 
        /// element with namespace 'http://docs.oasis-open.org/ws-sx/ws-trust/200512'.
        /// 
        /// The input argument is null.
        public override bool CanRead(XmlReader reader)
        {
            if (reader == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }
            return reader.IsStartElement(WSTrust13Constants.ElementNames.RequestSecurityTokenResponseCollection, WSTrust13Constants.NamespaceURI)
                || reader.IsStartElement(WSTrust13Constants.ElementNames.RequestSecurityTokenResponse, WSTrust13Constants.NamespaceURI);
        }
    }
}