/***********************************************************
Copyright (C) 2020 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.interfaces;

import javax.net.ssl.SSLHandshakeException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import com.verisign.epp.codec.gen.EPPMessage;
import com.verisign.epp.transport.client.EPPSSLClientSocket;


/**
 * Session that attempts to execute client-initiated renegotation prior to
 * sending a packet. This class is only used for test purposes and should never
 * be used outside of a test that validates that client-initiated renegotation
 * is disabled by the server. When this class is initiated it will make a TLS
 * connection to the server and when the {@code initSession()} is called, it
 * will result with an {@link EPPCommandException} with the cause
 * {@link SSLHandshakeException} when client-initiated renegotation is disabled.
 */
class RenegotiationSession extends EPPSession {

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

	/**
	 * Create the {@code SSLHandshakeException} session, which will establish a
	 * TLS connection with the server. The {@link #initSession()} method must be
	 * called to initialize the session with a login command.
	 * 
	 * @throws EPPCommandException
	 */
	public RenegotiationSession() throws EPPCommandException {
		super();
	}

	/**
	 * Attempt to execute the client-initiated renegotiation prior to sending
	 * each document. This will fail with an {@code IOException} when
	 * client-initiated renegotiation is disabled.
	 * 
	 * @param aDocument
	 *           DOM Document to send to the server encoded from the
	 *           {@code aMessage} parameter.
	 * @param aMessage
	 *           EPP message that was encoded to create the {@code aDocument}
	 *           parameter to send to the server.
	 * 
	 * @exception EPPCommandException
	 *               Error sending the command. This will be thrown with the
	 *               cause {@link SSLHandshakeException} when the server has
	 *               disabled client-initiated renegotiation.
	 */
	public void sendDocument(Document aDocument, EPPMessage aMessage) throws EPPCommandException {
		cat.debug("sendDocument(): enter");

		// Execute client-initiated renegotiation.
		if (super.connection instanceof EPPSSLClientSocket) {
			try {
				((EPPSSLClientSocket) super.connection).getSocket().startHandshake();

				super.sendDocument(aDocument, aMessage);
			}
			catch (EPPCommandException ex) {
				cat.error("sendDocument(): Exception executing client-initiated renegotiation: " + ex);
				throw ex;
			}
			catch (Exception ex) {
				cat.error("sendDocument(): Exception executing client-initiated renegotiation: " + ex);
				throw new EPPCommandException("RenegotiationSession.sendPacket() : " + ex.getMessage(), ex);
			}

			cat.info("sendDocument(): Executed client-initiated renegotiation successfully");
		}
		else {
			super.sendDocument(aDocument, aMessage);
		}

		cat.debug("sendDocument(): exit");
	}

}
