package com.sun.identity.saml2.protocol.impl;

import com.sun.identity.saml2.assertion.AssertionFactory;
import com.sun.identity.saml2.common.SAML2Exception;
import com.sun.identity.saml2.common.SAML2SDKUtils;
import com.sun.identity.saml2.protocol.LogoutResponse;
import com.sun.identity.saml2.protocol.ProtocolFactory;
import com.sun.identity.shared.xml.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class LogoutResponseImpl extends StatusResponseImpl implements LogoutResponse {
   public LogoutResponseImpl() {
      this.isMutable = true;
   }

   public LogoutResponseImpl(Element element) throws SAML2Exception {
      this.parseElement(element);
      if (this.isSigned) {
         this.signedXMLString = XMLUtils.print(element);
      }
   }

   public LogoutResponseImpl(String xmlString) throws SAML2Exception {
      Document xmlDocument = XMLUtils.toDOMDocument(xmlString, SAML2SDKUtils.DEBUG);
      if (xmlDocument == null) {
         throw new SAML2Exception(SAML2SDKUtils.BUNDLE.getString("errorObtainingElement"));
      }

      this.parseElement(xmlDocument.getDocumentElement());
      if (this.isSigned) {
         this.signedXMLString = xmlString;
      }
   }

   @Override
   public String toXMLString() throws SAML2Exception {
      return this.toXMLString(true, false);
   }

   @Override
   public String toXMLString(boolean includeNSPrefix, boolean declareNS) throws SAML2Exception {
      if (this.isSigned && this.signedXMLString != null) {
         return this.signedXMLString;
      }

      this.validateData();
      StringBuilder xmlString = new StringBuilder(1000);
      xmlString.append("<");
      if (includeNSPrefix) {
         xmlString.append("samlp:");
      }

      xmlString.append("LogoutResponse").append(" ");
      xmlString.append(super.toXMLString(includeNSPrefix, declareNS));
      xmlString.append("\n").append("</samlp:").append("LogoutResponse").append(">");
      return xmlString.toString();
   }

   @Override
   public void makeImmutable() {
      super.makeImmutable();
   }

   private void parseElement(Element element) throws SAML2Exception {
      AssertionFactory assertionFactory = AssertionFactory.getInstance();
      ProtocolFactory protoFactory = ProtocolFactory.getInstance();
      this.responseId = element.getAttribute("ID");
      this.validateID(this.responseId);
      this.version = element.getAttribute("Version");
      this.validateVersion(this.version);
      String issueInstantStr = element.getAttribute("IssueInstant");
      this.validateIssueInstant(issueInstantStr);
      this.destination = element.getAttribute("Destination");
      this.consent = element.getAttribute("Consent");
      this.inResponseTo = element.getAttribute("InResponseTo");
      NodeList nList = element.getChildNodes();
      if (nList != null && nList.getLength() > 0) {
         for (int i = 0; i < nList.getLength(); i++) {
            Node childNode = nList.item(i);
            String cName = childNode.getLocalName();
            if (cName != null) {
               if (cName.equals("Issuer")) {
                  this.issuer = assertionFactory.createIssuer((Element)childNode);
               } else if (cName.equals("Signature")) {
                  this.signatureString = XMLUtils.getElementString((Element)childNode);
                  this.isSigned = true;
               } else if (cName.equals("Extensions")) {
                  this.extensions = protoFactory.createExtensions((Element)childNode);
               } else if (cName.equals("Status")) {
                  this.status = protoFactory.createStatus((Element)childNode);
                  this.validateStatus();
               }
            }
         }
      }
   }
}
