/***********************************************************
Copyright (C) 2004 VeriSign, Inc.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

http://www.verisign.com/nds/naming/namestore/techdocs.html
***********************************************************/
package com.verisign.epp.namestore.interfaces;

import java.security.InvalidParameterException;

import com.verisign.epp.codec.gen.EPPResponse;
import com.verisign.epp.codec.namestoreext.EPPNamestoreExtNamestoreExt;
import com.verisign.epp.codec.orgext.EPPOrgExtCreate;
import com.verisign.epp.codec.orgext.EPPOrgExtId;
import com.verisign.epp.codec.orgext.EPPOrgExtUpdate;
import com.verisign.epp.interfaces.EPPCommandException;
import com.verisign.epp.interfaces.EPPContact;
import com.verisign.epp.interfaces.EPPSession;

/**
 * NameStore Contact interface that extends that standard
 * <code>EPPContact</code> by adding new methods
 * like @link{#setSubProductID(String)}. <code>EPPContact</code> could be used
 * directly, but <code>NSContact</code> can be enhanced independent of the EPP
 * specification.
 */
public class NSContact extends EPPContact {

	/**
	 * Used to specify the addition of an attribute with
	 * <code>addUpdateOrgId</code>.
	 */
	public static final int ADD = 1;

	/**
	 * Used to specify the removal of an attribute with
	 * <code>addUpdateOrgId</code>.
	 */
	public static final int REMOVE = 2;

	/**
	 * Used to specify the change of an attribute with
	 * <code>addUpdateOrgId</code>.
	 */
	public static final int CHANGE = 3;

	/**
	 * Org extension create
	 */
	private EPPOrgExtCreate orgCreate = null;

	/**
	 * Org extension update
	 */
	private EPPOrgExtUpdate orgUpdate = null;

	/**
	 * Creates an <code>NSContact</code> with an established
	 * <code>EPPSession</code>.
	 * 
	 * @param aSession
	 *           Established session
	 */
	public NSContact(EPPSession aSession) {
		super(aSession);
	}

	/**
	 * Sets the contact sub-product id which specifies which is the target
	 * registry for the contact operation. Some possible values included
	 * in @link{NSSubProduct}. This results in a
	 * <code>EPPNamestoreExtNamestoreExt</code> extension being added to the
	 * command.
	 * 
	 * @param aSubProductID
	 *           Sub-product id of host operation. Should use one of
	 *           the @link{NSSubProduct} constants or using the TLD value.
	 *           Passing <code>null</code> will not add any extension.
	 */
	public void setSubProductID(String aSubProductID) {
		if (aSubProductID != null) {
			super.addExtension(new EPPNamestoreExtNamestoreExt(aSubProductID));
		}
	}

	/**
	 * Adds an org identifier for use with {@link #sendCreate()}.
	 * 
	 * @param aOrgId
	 *           Org identifier with role to add
	 */
	public void addOrgId(EPPOrgExtId aOrgId) {
		if (this.orgCreate == null) {
			this.orgCreate = new EPPOrgExtCreate();
		}
		this.orgCreate.addOrgId(aOrgId);
	}

	/**
	 * Updates the org identifier used with {@link #sendUpdate()}. There are
	 * three possible actions that can be used including
	 * <code>NSContact.ADD</code>, <code>NSContact.REMOVE</code>, and
	 * <code>NSContact.CHANGE</code> for the org identifier.
	 * 
	 * @param aAction
	 *           One of the <code>NSContact.ADD</code>,
	 *           <code>NSContact.REMOVE</code>, and <code>NSContact.CHANGE</code>
	 *           for the org identifier.
	 * @param aOrgId
	 *           Org identifier to add, remove, or change
	 */
	public void addUpdateOrgId(int aAction, EPPOrgExtId aOrgId) {

		if (this.orgUpdate == null) {
			this.orgUpdate = new EPPOrgExtUpdate();
		}
		switch (aAction) {
			case NSContact.ADD:
				this.orgUpdate.addAddOrg(aOrgId);
				break;
			case NSContact.REMOVE:
				this.orgUpdate.addRemOrg(aOrgId);
				break;
			case NSContact.CHANGE:
				this.orgUpdate.addChgOrg(aOrgId);
				break;
			default:
				throw new InvalidParameterException("NSContact.updateOrgId(int, EPPOrgExtId): Invalid action " + aAction);
		}
	}

	/**
	 * Sends a Contact Create Command to the server.<br>
	 * <br>
	 * The required attributes have been set with the following methods:<br>
	 * <br>
	 *
	 * <ul>
	 * <li><code>addContactId</code> - Sets the contact to update. Only one
	 * contact is valid.</li>
	 * <li><code>setPostalContact</code> - Set the postal information</li>
	 * <li><code>setEmail</code> - Set the email address</li>
	 * <li><code>setAuthString</code> - Sets the contact authorization string.
	 * </li>
	 * </ul>
	 *
	 * <br>
	 * <br>
	 * The optional attributes have been set with the following:<br>
	 * <br>
	 *
	 * <ul>
	 * <li><code>setTransId</code> - Sets the client transaction identifier</li>
	 * <li><code>setExtension</code> - Command extension to send with command
	 * </li>
	 * <li><code>setVoicePhone</code> - Set the voice phone</li>
	 * <li><code>setFaxNumber</code> - Set the fax number</li>
	 * <li><code>setInterPostalPostalContact</code> - Set the international
	 * postal information</li>
	 * <li><code>addOrgId</code> - Add an organization identifier with a role
	 * </li>
	 * </ul>
	 *
	 *
	 * @return <code>EPPContactCreateResp</code> containing the contact create
	 *         result.
	 *
	 * @exception EPPCommandException
	 *               Error executing the update command. Use
	 *               <code>getResponse</code> to get the associated server error
	 *               response.
	 */
	@Override
	public EPPResponse sendCreate() throws EPPCommandException {
		if (this.orgCreate != null) {
			super.addExtension(this.orgCreate);
		}

		return super.sendCreate();
	}

	/**
	 * Sends a Contact Update Command to the server.<br>
	 * <br>
	 * The required attributes have been set with the following methods:<br>
	 * <br>
	 *
	 * <ul>
	 * <li><code>addContactId</code> - Sets the contact to update. Only one
	 * contact is valid.</li>
	 * </ul>
	 *
	 * <br>
	 * <br>
	 * The optional attributes have been set with the following:<br>
	 * <br>
	 *
	 * <ul>
	 * <li><code>setTransId</code> - Sets the client transaction identifier</li>
	 * <li><code>setExtension</code> - Command extension to send with command
	 * </li>
	 * <li><code>addStatus</code> - Add status</li>
	 * <li><code>removeStatus</code> - Remove status</li>
	 * <li><code>setPostalContact</code> - Set the postal information</li>
	 * <li><code>setVoicePhone</code> - Set the voice phone</li>
	 * <li><code>setFaxNumber</code> - Set the fax number</li>
	 * <li><code>setEmail</code> - Set the email address</li>
	 * <li><code>setInterPostalPostalContact</code> - Set the international
	 * postal information</li>
	 * <li><code>setAuthString</code> - Sets the contact authorization string.
	 * </li>
	 * <li><code>addUpdateOrgId</code> - Add an update to organization identifier
	 * </li>
	 * </ul>
	 *
	 * At least one update attribute needs to be set.
	 *
	 * @return <code>EPPResponse</code> containing the contact update result.
	 *
	 * @exception EPPCommandException
	 *               Error executing the update command. Use
	 *               <code>getResponse</code> to get the associated server error
	 *               response.
	 */
	@Override
	public EPPResponse sendUpdate() throws EPPCommandException {
		if (this.orgUpdate != null) {
			super.addExtension(this.orgUpdate);
		}

		return super.sendUpdate();
	}

	/**
	 * Resets the contact attributes for the next command.
	 */
	protected void resetContact() {
		super.resetContact();
		this.orgCreate = null;
		this.orgUpdate = null;
	}

} // End class NSContact
