/**************************************************************************
 *                                                                        *
 * The information in this document is proprietary to VeriSign, Inc.      *
 * It may not be used, reproduced or disclosed without the written        *
 * approval of VeriSign.                                                  *
 *                                                                        *
 * VERISIGN PROPRIETARY & CONFIDENTIAL INFORMATION                        *
 *                                                                        *
 *                                                                        *
 * Copyright (c) 2016 VeriSign, Inc.  All rights reserved.                *
 *                                                                        *
 *************************************************************************/

package com.verisign.epp.serverstub;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.verisign.epp.codec.contact.EPPContactCheckCmd;
import com.verisign.epp.codec.contact.EPPContactCreateCmd;
import com.verisign.epp.codec.contact.EPPContactDeleteCmd;
import com.verisign.epp.codec.contact.EPPContactInfoCmd;
import com.verisign.epp.codec.contact.EPPContactTransferCmd;
import com.verisign.epp.codec.contact.EPPContactUpdateCmd;
import com.verisign.epp.codec.gen.EPPResponse;
import com.verisign.epp.codec.namestoreext.EPPNamestoreExtNamestoreExt;
import com.verisign.epp.framework.EPPContactHandler;
import com.verisign.epp.framework.EPPEvent;
import com.verisign.epp.framework.EPPEventResponse;
import com.verisign.epp.serverstub.addlemail.AddlEmailContactHandler;
import com.verisign.epp.serverstub.secureauthinfo.v1_0.SecureAuthInfoContactHandler;

/**
 * The <code>NSContactHandler</code> class is a concrete implementation of the
 * abstract {@link com.verisign.epp.framework.EPPContactHandler} class. It
 * defines the Server's response to all received EPP contact Commands.
 * 
 * @author ssarpotdar
 * @version 1.0 Dec 13, 2016
 */
public class NSContactHandler extends EPPContactHandler {

	/** Constant server transaction id */
	private static final String svrTransId = "54322-XYZ";

	/** Constant ROID */
	private static final String roid = "NS1EXAMPLE1-VRSN";

	/** Logger category */
	private static Logger cat = LoggerFactory.getLogger(NSContactHandler.class);

	/** Epp contact handler as default handler for all contact commands. */
	ContactHandler contactHandler = new ContactHandler();

	/**
	 * Secure Authorization Information Contact Handler used for implementing the
	 * Secure Authorization Information for Transfer RFC 9154.
	 */
	SecureAuthInfoContactHandler secureAuthInfoContactHandler = new SecureAuthInfoContactHandler();

	/**
	 * Internationalized Email Addresses (EAI) Contact Handler used for
	 * implementing the Use of Internationalized Email Address draft
	 * (draft-ietf-regext-epp-eai).
	 */
	AddlEmailContactHandler addlEmailContactHandler = new AddlEmailContactHandler();

	/**
	 * Invoked when a Contact Create Command is received. The handler routes the
	 * command to the appropriate handler based on the extensions and data
	 * included in the command.
	 * 
	 * @param aEvent
	 *           The <code>EPPEvent</code> that is being handled
	 * 
	 * @param aData
	 *           Any data that a Server needs to send to this
	 *           <code>EPPContactHandler</code>
	 * 
	 * @return The response that should be sent back to the client.
	 * 
	 * @see com.verisign.epp.framework.EPPContactHandler#doContactCreate(com.verisign.epp.framework.EPPEvent,
	 *      java.lang.Object)
	 */
	@Override
	protected EPPEventResponse doContactCreate(EPPEvent aEvent, Object aData) {
		EPPContactCreateCmd theCommand = (EPPContactCreateCmd) aEvent.getMessage();
		cat.debug("doContactCreate: command = [" + theCommand + "]");

		// Secure Auth Info contact?
		if (theCommand.getId().startsWith("SAI")) {
			EPPEventResponse secureAuthInfoResp = secureAuthInfoContactHandler.doContactCreate(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) secureAuthInfoResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return secureAuthInfoResp;
		} // EAI contact?
		else if (theCommand.getId().startsWith("AE-")) {
			EPPEventResponse eaiResp = addlEmailContactHandler.doContactCreate(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) eaiResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return eaiResp;
		}

		EPPEventResponse contactCreateResponse = this.contactHandler.doContactCreate(aEvent, aData);
		return contactCreateResponse;
	}

	/**
	 * Invoked when a Contact Delete Command is received. The handler routes the
	 * command to the appropriate handler based on the extensions and data
	 * included in the command.
	 * 
	 * @param aEvent
	 *           The <code>EPPEvent</code> that is being handled
	 * 
	 * @param aData
	 *           Any data that a Server needs to send to this
	 *           <code>EPPContactHandler</code>
	 * 
	 * @return The response that should be sent back to the client.
	 * 
	 * @see com.verisign.epp.framework.EPPContactHandler#doContactDelete(com.verisign.epp.framework.EPPEvent,
	 *      java.lang.Object)
	 */
	@Override
	protected EPPEventResponse doContactDelete(EPPEvent aEvent, Object aData) {
		EPPContactDeleteCmd theCommand = (EPPContactDeleteCmd) aEvent.getMessage();
		cat.debug("doContactDelete: command = [" + theCommand + "]");

		EPPEventResponse contactDeleteResponse = this.contactHandler.doContactDelete(aEvent, aData);

		return contactDeleteResponse;
	}

	/**
	 * Invoked when a Contact Info Command is received. The handler routes the
	 * command to the appropriate handler based on the extensions and data
	 * included in the command.
	 * 
	 * @param aEvent
	 *           The <code>EPPEvent</code> that is being handled
	 * 
	 * @param aData
	 *           Any data that a Server needs to send to this
	 *           <code>EPPContactHandler</code>
	 * 
	 * @return The response that should be sent back to the client.
	 * 
	 * @see com.verisign.epp.framework.EPPContactHandler#doContactInfo(com.verisign.epp.framework.EPPEvent,
	 *      java.lang.Object)
	 */
	@Override
	protected EPPEventResponse doContactInfo(EPPEvent aEvent, Object aData) {
		EPPContactInfoCmd theCommand = (EPPContactInfoCmd) aEvent.getMessage();
		cat.debug("doContactInfo: command = [" + theCommand + "]");

		// Secure Auth Info domain?
		if (theCommand.getId().startsWith("SAI")) {
			EPPEventResponse secureAuthInfoResp = secureAuthInfoContactHandler.doContactInfo(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) secureAuthInfoResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return secureAuthInfoResp;
		} // EAI contact?
		else if (theCommand.getId().startsWith("AE-")) {
			EPPEventResponse eaiResp = addlEmailContactHandler.doContactInfo(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) eaiResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return eaiResp;
		}

		EPPEventResponse contactInfoResponse = this.contactHandler.doContactInfo(aEvent, aData);
		return contactInfoResponse;
	}

	/**
	 * Invoked when a Contact Check Command is received. The handler routes the
	 * command to the appropriate handler based on the extensions and data
	 * included in the command.
	 * 
	 * @param aEvent
	 *           The <code>EPPEvent</code> that is being handled
	 * 
	 * @param aData
	 *           Any data that a Server needs to send to this
	 *           <code>EPPContactHandler</code>
	 * 
	 * @return The response that should be sent back to the client.
	 * 
	 * @see com.verisign.epp.framework.EPPContactHandler#doContactCheck(com.verisign.epp.framework.EPPEvent,
	 *      java.lang.Object)
	 */
	@Override
	protected EPPEventResponse doContactCheck(EPPEvent aEvent, Object aData) {
		EPPContactCheckCmd theCommand = (EPPContactCheckCmd) aEvent.getMessage();
		cat.debug("doContactCheck: command = [" + theCommand + "]");

		EPPEventResponse contactCheckResponse = this.contactHandler.doContactCheck(aEvent, aData);

		return contactCheckResponse;
	}

	/**
	 * Invoked when a Contact Transfer Command is received. The handler routes
	 * the command to the appropriate handler based on the extensions and data
	 * included in the command.
	 * 
	 * @param aEvent
	 *           The <code>EPPEvent</code> that is being handled
	 * 
	 * @param aData
	 *           Any data that a Server needs to send to this
	 *           <code>EPPContactHandler</code>
	 * 
	 * @return The response that should be sent back to the client.
	 * 
	 * @see com.verisign.epp.framework.EPPContactHandler#doContactTransfer(com.verisign.epp.framework.EPPEvent,
	 *      java.lang.Object)
	 */
	@Override
	protected EPPEventResponse doContactTransfer(EPPEvent aEvent, Object aData) {
		EPPContactTransferCmd theCommand = (EPPContactTransferCmd) aEvent.getMessage();
		cat.debug("doContactTransfer: command = [" + theCommand + "]");

		// Secure Auth Info domain?
		if (theCommand.getId().startsWith("SAI")) {
			EPPEventResponse secureAuthInfoResp = secureAuthInfoContactHandler.doContactTransfer(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) secureAuthInfoResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return secureAuthInfoResp;
		}

		EPPEventResponse contactTransferResponse = this.contactHandler.doContactTransfer(aEvent, aData);

		return contactTransferResponse;
	}

	/**
	 * Invoked when a Contact Update Command is received. The handler routes the
	 * command to the appropriate handler based on the extensions and data
	 * included in the command.
	 * 
	 * @param aEvent
	 *           The <code>EPPEvent</code> that is being handled
	 * 
	 * @param aData
	 *           Any data that a Server needs to send to this
	 *           <code>EPPContactHandler</code>
	 * 
	 * @return The response that should be sent back to the client.
	 * 
	 * @see com.verisign.epp.framework.EPPContactHandler#doContactUpdate(com.verisign.epp.framework.EPPEvent,
	 *      java.lang.Object)
	 */
	@Override
	protected EPPEventResponse doContactUpdate(EPPEvent aEvent, Object aData) {
		EPPContactUpdateCmd theCommand = (EPPContactUpdateCmd) aEvent.getMessage();
		cat.debug("doContactUpdate: command = [" + theCommand + "]");

		// Secure Auth Info domain?
		if (theCommand.getId().startsWith("SAI")) {
			EPPEventResponse secureAuthInfoResp = secureAuthInfoContactHandler.doContactUpdate(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) secureAuthInfoResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return secureAuthInfoResp;
		} // EAI contact?
		else if (theCommand.getId().startsWith("AE-")) {
			EPPEventResponse eaiResp = addlEmailContactHandler.doContactUpdate(aEvent, aData);

			// Mirror NameStore Extension in response
			if (theCommand.hasExtension(EPPNamestoreExtNamestoreExt.class)) {
				((EPPResponse) eaiResp.getResponse())
				      .addExtension(theCommand.getExtension(EPPNamestoreExtNamestoreExt.class));
			}

			return eaiResp;
		}

		EPPEventResponse contactUpdateResponse = this.contactHandler.doContactUpdate(aEvent, aData);
		return contactUpdateResponse;
	}

}
