/***********************************************************
Copyright (C) 2015 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.validate.v02;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import com.verisign.epp.codec.gen.EPPCodecComponent;
import com.verisign.epp.codec.gen.EPPResponse;
import com.verisign.epp.codec.validate.v02.EPPValidateCheckCmd;
import com.verisign.epp.codec.validate.v02.EPPValidateCheckResp;
import com.verisign.epp.codec.validate.v02.EPPValidateContact;
import com.verisign.epp.interfaces.EPPCommandException;
import com.verisign.epp.interfaces.EPPSession;

/**
 * {@code EPPValidate} is the primary client interface class used
 * for the Validate EPP mapping. An instance of
 * {@code EPPValidate} is created with an initialized
 * {@code EPPSession}, and can be used for more than one request within a
 * single thread. A set of setter methods are provided to set the attributes
 * before a call to one of the send action methods. The responses returned from
 * the send action methods are either instances of {@code EPPResponse} or
 * instances of response classes in the
 * {@code com.verisign.epp.codec.validate} package.
 *
 * @see com.verisign.epp.codec.validate.v02.EPPValidateCheckResp
 */
public class EPPValidate {

  /**
   * An instance of a session.
   */
  private EPPSession session = null;

  /**
   * Transaction Id provided by client
   */
  private String transId = null;

  /**
   * Extension objects associated with the command. This is a
   * {@code Vector} of {@code EPPCodecComponent} objects.
   */
  private Vector extensions = null;

  /**
   * Contacts used for the check command.
   */
  private List<EPPValidateContact> contacts = new ArrayList<EPPValidateContact>();

  /**
   * Constructs an {@code EPPValidate} given an initialized EPP
   * session.
   *
   * @param aSession
   *            Server session to use.
   */
  public EPPValidate(EPPSession aSession) {
    this.session = aSession;

    return;
  }

  /**
   * Adds a command extension object.
   *
   * @param aExtension
   *            command extension object associated with the command
   */
  public void addExtension(EPPCodecComponent aExtension) {
    if (this.extensions == null) {
      this.extensions = new Vector();
    }

    this.extensions.addElement(aExtension);
  }

  /**
   * Sets the command extension objects.
   *
   * @param aExtensions
   *            command extension objects associated with the command
   */
  public void setExtensions(Vector aExtensions) {
    this.extensions = aExtensions;
  }

  /**
   * Gets the command extensions.
   *
   * @return {@code Vector} of concrete {@code EPPCodecComponent}
   *         associated with the command if exists; {@code null}
   *         otherwise.
   */
  public Vector getExtensions() {
    return this.extensions;
  }

  /**
   * Sets the client transaction identifier.
   *
   * @param aTransId
   *            Client transaction identifier
   */
  public void setTransId(String aTransId) {
    this.transId = aTransId;
  }

  /**
   * Add a contact to the list of contacts.
   * 
   * @param aContact
   *            Contact to add to list of contacts to validate.
   */
  public void addContact(EPPValidateContact aContact) {
    this.contacts.add(aContact);
  }


  /**
   * Sends an Validate Check Command to the server.<br>
   * <br>
   * The required attributes that must be set prior to executing
   * {@code sendCheck()} include:<br>
   * <br>
   * <ul>
   * <li>{@code addLabel(String)} - Add at least one domain label to
   * check.</li>
   * </ul>
   * <br>
   * <br>
   * The optional attributes can be set with the following:<br>
   * <br>
   * <ul>
   * <li>{@code setTransId} - Sets the client transaction identifier.</li>
   * </ul>
   * 
   * @return {@code EPPValidateCheckResp}.
   * 
   * @throws EPPCommandException
   *             On error
   */
  public EPPValidateCheckResp sendCheck() throws EPPCommandException {

    if (this.contacts == null || this.contacts.isEmpty()) {
      throw new EPPCommandException(
          "At least one contact must be set for sendCheck()");
    }

    // Create the command
    EPPValidateCheckCmd theCommand = new EPPValidateCheckCmd(
        this.transId, this.contacts);

    // Set command extension
    theCommand.setExtensions(this.extensions);

    // Reset attributes
    this.resetValidate();

    // process the command and response
    return (EPPValidateCheckResp) this.session.processDocument(
        theCommand, EPPValidateCheckResp.class);
  }


  /**
   * Resets the Validate instance to its initial state.
   */
  protected void resetValidate() {
    this.contacts = new ArrayList<EPPValidateContact>();
  }

  /**
   * Gets the response associated with the last command. This method can be
   * used to retrieve the server error response in the catch block of
   * EPPCommandException.
   *
   * @return Response associated with the last command
   */
  public EPPResponse getResponse() {
    return this.session.getResponse();
  }

}
