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

import java.util.Date;
import java.util.GregorianCalendar;

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

import com.verisign.epp.codec.gen.EPPResponse;
import com.verisign.epp.codec.gen.EPPResult;
import com.verisign.epp.codec.gen.EPPTransId;
import com.verisign.epp.codec.org.EPPOrgAddress;
import com.verisign.epp.codec.org.EPPOrgCheckCmd;
import com.verisign.epp.codec.org.EPPOrgCheckResp;
import com.verisign.epp.codec.org.EPPOrgCheckResult;
import com.verisign.epp.codec.org.EPPOrgContact;
import com.verisign.epp.codec.org.EPPOrgCreateCmd;
import com.verisign.epp.codec.org.EPPOrgCreateResp;
import com.verisign.epp.codec.org.EPPOrgDeleteCmd;
import com.verisign.epp.codec.org.EPPOrgInfoCmd;
import com.verisign.epp.codec.org.EPPOrgInfoResp;
import com.verisign.epp.codec.org.EPPOrgPendActionMsg;
import com.verisign.epp.codec.org.EPPOrgPostalDefinition;
import com.verisign.epp.codec.org.EPPOrgRole;
import com.verisign.epp.codec.org.EPPOrgRoleStatus;
import com.verisign.epp.codec.org.EPPOrgStatus;
import com.verisign.epp.codec.org.EPPOrgUpdateCmd;
import com.verisign.epp.framework.EPPEvent;
import com.verisign.epp.framework.EPPEventResponse;
import com.verisign.epp.framework.EPPHandleEventException;
import com.verisign.epp.framework.EPPOrgHandler;
import com.verisign.epp.framework.EPPPollQueueException;
import com.verisign.epp.framework.EPPPollQueueMgr;


/**
 * The <code>OrgHandler</code> class extends <code>EPPOrgHandler</code> to
 * include handling the Org Mapping commands.
 */
public class OrgHandler extends EPPOrgHandler {

  /** Category for logging */
      private static Logger cat = LoggerFactory.getLogger(OrgHandler.class);

  /**
   * Constructs an instance of IdnMapDomainHandler
   */
  public OrgHandler() {
  }

  /**
   * Do any pre-handling of commands.
   *
   * @param aEvent
   *           The <code>EPPEvent</code> that is being handled
   * @param aData
   *           Any data that a Server needs to send to this
   *           <code>OrgHandler</code> This is assumed to be an instance of
   *           SessionData here.
   *
   * @exception EPPHandleEventException
   *               Thrown if an error condition occurs. It must contain an
   *               <code>EPPEventResponse</code>
   */
  protected void preHandleEvent(EPPEvent aEvent, Object aData) throws EPPHandleEventException {

    super.preHandleEvent(aEvent, aData);

  }

  /**
   * Override base handler <code>doOrgCheck</code> method and add handling of
   * the Org Check Command.
   * 
   * @param aEvent
   *           The <code>EPPEvent</code> that is being handled
   * @param aData
   *           Any data that a Server needs to send to this
   *           <code>OrgHandler</code>
   *
   * @return EPPEventResponse The response that should be sent back to the
   *         client.
   */
  protected EPPEventResponse doOrgCheck(EPPEvent aEvent, Object aData) {
    cat.debug("doOrgCheck: enter");

    EPPOrgCheckCmd theCommand = (EPPOrgCheckCmd) aEvent.getMessage();

    EPPTransId theTransId = new EPPTransId(theCommand.getTransId(), "54321-XYZ");

    EPPOrgCheckResp theResp = new EPPOrgCheckResp(theTransId);

    for (String orgId : theCommand.getOrgIds()) {
      if (orgId.equalsIgnoreCase("re1523") || orgId.equalsIgnoreCase("notavailable")) {
        theResp.addCheckResult(new EPPOrgCheckResult(orgId, "In use"));
      }
      else {
        theResp.addCheckResult(new EPPOrgCheckResult(orgId, true));
      }
    }

    cat.debug("doOrgCheck: exit");
    return new EPPEventResponse(theResp);
  }

  /**
   * Override base handler <code>doOrgInfo</code> method and add handling of
   * the Org Info Command.
   * 
   * @param aEvent
   *           The <code>EPPEvent</code> that is being handled
   * @param aData
   *           Any data that a Server needs to send to this
   *           <code>OrgHandler</code>
   *
   * @return EPPEventResponse The response that should be sent back to the
   *         client.
   */
  protected EPPEventResponse doOrgInfo(EPPEvent aEvent, Object aData) {
    cat.debug("doOrgInfo: enter");

    EPPOrgInfoCmd theCommand = (EPPOrgInfoCmd) aEvent.getMessage();

    EPPTransId theTransId = new EPPTransId(theCommand.getTransId(), "54321-XYZ");

    EPPOrgInfoResp theResp = new EPPOrgInfoResp(theTransId, theCommand.getOrgId());
    theResp.setRoid("registrar1362-REP");
    theResp.addRole(new EPPOrgRole("registrar", EPPOrgRoleStatus.ok, "1362"));
    theResp.addStatus(EPPOrgStatus.ok);
    theResp.setParentId("1523res");

    EPPOrgAddress theAddress = new EPPOrgAddress();
    theAddress.setStreets("124 Example Dr.", "Suite 200");
    theAddress.setCity("Dulles");
    theAddress.setStateProvince("VA");
    theAddress.setPostalCode("20166-6503");
    theAddress.setCountry("US");

    theResp
          .addPostalInfo(new EPPOrgPostalDefinition(EPPOrgPostalDefinition.Type.INT, "Example Org Inc.", theAddress));
    theResp.setVoice("+1.7035555555");
    theResp.setVoiceExt("1234");
    theResp.setFax("+1.7035555556");
    theResp.setEmail("contact@org.example");
    theResp.setUrl("http://org.example");
    theResp.addContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.ADMINISTRATIVE));
    theResp.addContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.BILLING));
    theResp.addContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.CUSTOM, "customSample"));
    theResp.setClientId("ClientY");
    theResp.setCreatedBy("ClientX");
    theResp.setCreatedDate(new GregorianCalendar(1999, 04, 03, 22, 0).getTime());
    theResp.setLastUpdatedBy("ClientX");
    theResp.setLastUpdatedDate(new GregorianCalendar(1999, 12, 03, 0, 0).getTime());

    cat.debug("doOrgInfo: exit");
    return new EPPEventResponse(theResp);
  }

  /**
   * Override base handler <code>doOrgCreate</code> method and add handling of
   * the Org Create Command.
   * 
   * @param aEvent
   *           The <code>EPPEvent</code> that is being handled
   * @param aData
   *           Any data that a Server needs to send to this
   *           <code>OrgHandler</code>
   *
   * @return EPPEventResponse The response that should be sent back to the
   *         client.
   */
  protected EPPEventResponse doOrgCreate(EPPEvent aEvent, Object aData) {
    cat.debug("doOrgCreate: enter");

    EPPOrgCreateCmd theCommand = (EPPOrgCreateCmd) aEvent.getMessage();

    EPPTransId theTransId = new EPPTransId(theCommand.getTransId(), "54321-XYZ");

    EPPOrgCreateResp theResp = new EPPOrgCreateResp(theTransId, theCommand.getOrgId(), new Date());

    if (theCommand.getOrgId().equalsIgnoreCase("PENDING")) {
      theResp.setResult(EPPResult.SUCCESS_PENDING);

      EPPTransId thePendingTransId = new EPPTransId(theCommand.getTransId(), "54321-XYZ");

      // Add the pending action poll message
      EPPOrgPendActionMsg theMsg = new EPPOrgPendActionMsg(null, theCommand.getOrgId(), true, thePendingTransId,
            new Date());

      try {
        EPPPollQueueMgr.getInstance().put(null, OrgPollHandler.KIND, theMsg, null);
      }
      catch (EPPPollQueueException ex) {
        cat.error("Exception inserting poll message: " + ex);
        theResp.setResult(EPPResult.COMMAND_FAILED);
      }
    }

    cat.debug("doOrgCreate: exit");
    return new EPPEventResponse(theResp);
  }

  /**
   * Override base handler <code>doOrgDelete</code> method and add handling of
   * the Org Delete Command.
   * 
   * @param aEvent
   *           The <code>EPPEvent</code> that is being handled
   * @param aData
   *           Any data that a Server needs to send to this
   *           <code>OrgHandler</code>
   *
   * @return EPPEventResponse The response that should be sent back to the
   *         client.
   */
  protected EPPEventResponse doOrgDelete(EPPEvent aEvent, Object aData) {
    cat.debug("doOrgDelete: enter");

    EPPOrgDeleteCmd theCommand = (EPPOrgDeleteCmd) aEvent.getMessage();

    EPPTransId theTransId = new EPPTransId(theCommand.getTransId(), "54321-XYZ");

    EPPResponse theResp = new EPPResponse(theTransId);

    cat.debug("doOrgDelete: exit");
    return new EPPEventResponse(theResp);
  }

  /**
   * Override base handler <code>doOrgUpdate</code> method and add handling of
   * the Org Update Command.
   * 
   * @param aEvent
   *           The <code>EPPEvent</code> that is being handled
   * @param aData
   *           Any data that a Server needs to send to this
   *           <code>OrgHandler</code>
   *
   * @return EPPEventResponse The response that should be sent back to the
   *         client.
   */
  protected EPPEventResponse doOrgUpdate(EPPEvent aEvent, Object aData) {
    cat.debug("doOrgUpdate: enter");

    EPPOrgUpdateCmd theCommand = (EPPOrgUpdateCmd) aEvent.getMessage();

    EPPTransId theTransId = new EPPTransId(theCommand.getTransId(), "54321-XYZ");

    EPPResponse theResp = new EPPResponse(theTransId);

    cat.debug("doOrgUpdate: exit");
    return new EPPEventResponse(theResp);
  }

}
