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

import com.sun.identity.saml2.common.SAML2Exception;
import com.sun.identity.saml2.common.SAML2SDKUtils;
import com.sun.identity.saml2.protocol.IDPEntry;
import com.sun.identity.shared.xml.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class IDPEntryImpl implements IDPEntry {
   private static final String PROVIDERID = "ProviderID";
   private static final String NAME = "Name";
   static final String LOC = "Loc";
   private String providerID;
   private String name;
   private String locationURI;
   private boolean isMutable;

   public IDPEntryImpl() {
      this.isMutable = true;
   }

   public IDPEntryImpl(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());
   }

   @Override
   public String getProviderID() {
      return this.providerID;
   }

   @Override
   public void setProviderID(String uri) throws SAML2Exception {
      if (this.isMutable) {
         this.providerID = uri;
      } else {
         throw new SAML2Exception(SAML2SDKUtils.BUNDLE.getString("objectImmutable"));
      }
   }

   @Override
   public String getName() {
      return this.name;
   }

   @Override
   public void setName(String name) throws SAML2Exception {
      if (this.isMutable) {
         this.name = name;
      } else {
         throw new SAML2Exception(SAML2SDKUtils.BUNDLE.getString("objectImmutable"));
      }
   }

   @Override
   public String getLoc() {
      return this.locationURI;
   }

   @Override
   public void setLoc(String locationURI) throws SAML2Exception {
      if (this.isMutable) {
         this.locationURI = locationURI;
      } else {
         throw new SAML2Exception(SAML2SDKUtils.BUNDLE.getString("objectImmutable"));
      }
   }

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

   @Override
   public String toXMLString(boolean includeNSPrefix, boolean declareNS) throws SAML2Exception {
      this.validate(this.providerID);
      StringBuilder xmlString = new StringBuilder(100);
      xmlString.append("<");
      if (includeNSPrefix) {
         xmlString.append("samlp:");
      }

      xmlString.append("IDPEntry");
      if (declareNS) {
         xmlString.append(" xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"");
      }

      xmlString.append(" ").append("ProviderID").append("=").append("\"").append(this.providerID).append("\"");
      if (this.name != null && !this.name.isEmpty()) {
         xmlString.append(" ").append("Name").append("=").append("\"").append(this.name).append("\"");
      }

      if (this.locationURI != null && !this.locationURI.isEmpty()) {
         xmlString.append(" ").append("Loc").append("=").append("\"").append(this.locationURI).append("\"");
      }

      xmlString.append(">").append("\n").append("</samlp:").append("IDPEntry").append(">");
      return xmlString.toString();
   }

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

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

   private void parseElement(Element element) throws SAML2Exception {
      this.providerID = element.getAttribute("ProviderID");
      this.validate(this.providerID);
      this.name = element.getAttribute("Name");
      this.locationURI = element.getAttribute("Loc");
   }

   private void validate(String providerID) throws SAML2Exception {
      if (providerID == null || providerID.isEmpty()) {
         SAML2SDKUtils.DEBUG.message("ProviderID is required");
         throw new SAML2Exception(SAML2SDKUtils.BUNDLE.getString("providerIDMissing"));
      }
   }
}
