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

import com.sun.identity.saml2.assertion.AssertionIDRef;
import com.sun.identity.saml2.common.SAML2Exception;
import com.sun.identity.saml2.common.SAML2Utils;
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 AssertionIDRefImpl implements AssertionIDRef {
   private String value;
   private boolean mutable = true;

   public AssertionIDRefImpl() {
   }

   public AssertionIDRefImpl(Element element) throws SAML2Exception {
      this.parseElement(element);
   }

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

      this.parseElement(doc.getDocumentElement());
   }

   @Override
   public String getValue() {
      return this.value;
   }

   @Override
   public void setValue(String value) throws SAML2Exception {
      if (!this.mutable) {
         throw new SAML2Exception(SAML2Utils.BUNDLE.getString("objectImmutable"));
      }

      this.value = value;
   }

   @Override
   public void makeImmutable() {
      this.mutable = false;
   }

   @Override
   public boolean isMutable() {
      return this.mutable;
   }

   @Override
   public String toXMLString(boolean includeNS, boolean declareNS) throws SAML2Exception {
      if (this.value != null && !this.value.trim().isEmpty()) {
         String prefix = "";
         String uri = "";
         if (includeNS) {
            prefix = "saml:";
         }

         if (declareNS) {
            uri = " xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\"";
         }

         return "<" + prefix + "AssertionIDRef" + uri + ">" + this.value + "</" + prefix + "AssertionIDRef>";
      } else {
         if (SAML2Utils.DEBUG.messageEnabled()) {
            SAML2Utils.DEBUG.message("AssertionIDRefImpl.toXMLString: AssertionIDRef value is null or empty.");
         }

         throw new SAML2Exception(SAML2Utils.BUNDLE.getString("emptyElementValue"));
      }
   }

   private void parseElement(Element element) throws SAML2Exception {
      if (element == null) {
         SAML2Utils.DEBUG.message("AssertionIDRefImpl.parseElement: Input is null.");
         throw new SAML2Exception(SAML2Utils.BUNDLE.getString("nullInput"));
      }

      String tag = element.getLocalName();
      if (!"AssertionIDRef".equals(tag)) {
         SAML2Utils.DEBUG.message("AssertionIDRefImpl.parseElement: Element local name is not AssertionIDRef.");
         throw new SAML2Exception(SAML2Utils.BUNDLE.getString("wrongInput"));
      }

      NodeList nodes = element.getChildNodes();
      int nodeCount = nodes.getLength();
      if (nodeCount > 0) {
         for (int i = 0; i < nodeCount; i++) {
            Node currentNode = nodes.item(i);
            if (currentNode.getNodeType() == 1) {
               if (SAML2Utils.DEBUG.messageEnabled()) {
                  SAML2Utils.DEBUG.message("AssertionIDRefImpl.parseElement: AssertionIDRef can't have child element.");
               }

               throw new SAML2Exception(SAML2Utils.BUNDLE.getString("wrongInput"));
            }
         }
      }

      this.value = XMLUtils.getElementValue(element);
      if (this.value != null && !this.value.trim().isEmpty()) {
         this.mutable = false;
      } else {
         if (SAML2Utils.DEBUG.messageEnabled()) {
            SAML2Utils.DEBUG.message("AssertionIDRefImpl.parseElement: AssertionIDRef value is null or empty.");
         }

         throw new SAML2Exception(SAML2Utils.BUNDLE.getString("emptyElementValue"));
      }
   }
}
