/***********************************************************
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.codec.orgext;

//----------------------------------------------
//
// imports...
//
//----------------------------------------------

// JUNIT Imports
import java.util.Date;
import java.util.Vector;

import com.verisign.epp.codec.domain.EPPDomainCreateCmd;
import com.verisign.epp.codec.domain.EPPDomainInfoResp;
import com.verisign.epp.codec.domain.EPPDomainPeriod;
import com.verisign.epp.codec.domain.EPPDomainStatus;
import com.verisign.epp.codec.domain.EPPDomainUpdateCmd;
import com.verisign.epp.codec.gen.EPPAuthInfo;
import com.verisign.epp.codec.gen.EPPCodecException;
import com.verisign.epp.codec.gen.EPPCodecTst;
import com.verisign.epp.codec.gen.EPPEncodeDecodeStats;
import com.verisign.epp.codec.gen.EPPFactory;
import com.verisign.epp.codec.gen.EPPResult;
import com.verisign.epp.codec.gen.EPPTransId;
import com.verisign.epp.util.TestThread;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * Is a unit test of the com.verisign.epp.codec.orgext package. The unit test
 * will execute, gather statistics, and output the results of a test of each
 * com.verisign.epp.codec.orgext package concrete extension
 * <code>EPPCodecComponent</code>'s.
 */
public class EPPOrgExtTst {
  /**
   * Number of unit test iterations to run. This is set in
   * <code>EPPCodecTst.main</code>
   */
  static private long numIterations = 1;

  /**
   * Unit test of using the <code>EPPOrgExtCreate</code> extension with a
   * domain create command.
   */
  @Test
  public void testOrgExtCreate() {
    EPPCodecTst.printStart("testOrgExtCreate");

    // Generic objects
    EPPEncodeDecodeStats theStats;

    // -- Extend Domain Create Command
    EPPDomainCreateCmd theDomainCommand1;
    theDomainCommand1 = new EPPDomainCreateCmd("ABC-12345", "example.com", new EPPAuthInfo("fooBAR"));
    theDomainCommand1.setPeriod(new EPPDomainPeriod(EPPDomainPeriod.PERIOD_UNIT_YEAR, 3));
    theDomainCommand1.addServer("ns1.example.com");

    EPPDomainCreateCmd theDomainCommand2 = null;
    try {
      theDomainCommand2 = (EPPDomainCreateCmd) theDomainCommand1.clone();
    }
    catch (CloneNotSupportedException e) {
      Assert.fail("CloneNotSupportedException cloning the EPPDomainCreateCmd: " + e);
    }

    // Add Extension
    theDomainCommand1.addExtension(new EPPOrgExtCreate(new EPPOrgExtId("reseller", "myreseller")));

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand1);
    System.out.println(theStats);

    // Add multiple organizations
    EPPOrgExtCreate theExt = new EPPOrgExtCreate();
    theExt.addOrgId(new EPPOrgExtId("reseller", "myreseller"));
    theExt.addOrgId(new EPPOrgExtId("privacyproxy", "myproxy"));
    theDomainCommand2.addExtension(theExt);

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand2);
    System.out.println(theStats);

    EPPCodecTst.printEnd("testOrgExtCreate");
  }

  /**
   * Unit test of using the <code>EPPOrgInfData</code> extension with a domain
   * info response. The tests include:<br>
   * <ol>
   * <li>TEST1 - Test with just the required org identifier</li>
   * <li>TEST2 - Test with both the org identifier and the org name</li>
   * </ol>
   */
  @Test
  public void testOrgExtInfData() {
    EPPCodecTst.printStart("testOrgExtInfData");

    // Generic objects
    EPPEncodeDecodeStats theStats;

    // -- TEST1 - Test with two organizations
    Vector statuses = new Vector();
    statuses.addElement(new EPPDomainStatus(EPPDomainStatus.ELM_STATUS_OK));
    EPPTransId respTransId = new EPPTransId("ngcl-IvJjzMZc", "test142AWQONJZ");
    EPPDomainInfoResp theResponse1 = new EPPDomainInfoResp(respTransId, "EXAMPLE1-REP", "example.com", "ClientX", statuses,
          "ClientY", new Date(), new EPPAuthInfo("2fooBAR"));
    theResponse1.setResult(EPPResult.SUCCESS);

    EPPDomainInfoResp theResponse2 = null;
    try {
      theResponse2 = (EPPDomainInfoResp) theResponse1.clone();
    }
    catch (CloneNotSupportedException e) {
      Assert.fail("CloneNotSupportedException cloning the EPPDomainInfoResp: " + e);
    }

    // Add Extension with two organizations
    EPPOrgExtInfData theExt = new EPPOrgExtInfData();
    theExt.addOrgId(new EPPOrgExtId("reseller", "myreseller"));
    theExt.addOrgId(new EPPOrgExtId("privacyproxy", "myproxy"));
    theResponse1.addExtension(theExt);

    theStats = EPPCodecTst.testEncodeDecode(theResponse1);
    System.out.println(theStats);

    // -- TEST2 - Test with no organizations
    // Add Extension
    theResponse2.addExtension(new EPPOrgExtInfData());

    theStats = EPPCodecTst.testEncodeDecode(theResponse2);
    System.out.println(theStats);

    EPPCodecTst.printEnd("testOrgExtInfData");
  }

  /**
   * Unit test of using the <code>EPPOrgExtUpdate</code> extension with a
   * domain update command. The tests include:<br>
   * <ol>
   * <li>TEST1 - Test adding a org identifier</li>
   * <li>TEST2 - Test removing a org identifier</li>
   * <li>TEST3 - Test changing a org identifier</li>
   * </ol>
   */
  @Test
  public void testOrgExtUpdate() {
    EPPCodecTst.printStart("testOrgExtUpdate");

    // Generic objects
    EPPEncodeDecodeStats theStats;

    // -- TEST1 - Test adding a reseller.
    EPPDomainUpdateCmd theDomainCommand;
    theDomainCommand = new EPPDomainUpdateCmd("ABC-12345", "example.com", null, null, null);

    EPPOrgExtUpdate theExt = new EPPOrgExtUpdate();
    theExt.addAddOrg(new EPPOrgExtId("reseller", "myreseller"));

    theDomainCommand.addExtension(theExt);

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand);
    System.out.println(theStats);

    // -- TEST2 - Test adding multiple organizations
    theDomainCommand = new EPPDomainUpdateCmd("ABC-12345", "example.com", null, null, null);

    theExt = new EPPOrgExtUpdate();
    theExt.addAddOrg(new EPPOrgExtId("reseller", "myreseller"));
    theExt.addAddOrg(new EPPOrgExtId("privacyproxy", "myproxy"));

    theDomainCommand.addExtension(theExt);

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand);
    System.out.println(theStats);

    // -- TEST3 - Test removing a reseller.
    theDomainCommand = new EPPDomainUpdateCmd("ABC-12345", "example.com", null, null, null);

    theExt = new EPPOrgExtUpdate();
    theExt.addRemOrg(new EPPOrgExtId("reseller", "myreseller"));

    theDomainCommand.addExtension(theExt);

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand);
    System.out.println(theStats);

    // -- TEST4 - Test removing multiple organizations
    theDomainCommand = new EPPDomainUpdateCmd("ABC-12345", "example.com", null, null, null);

    theExt = new EPPOrgExtUpdate();
    theExt.addRemOrg(new EPPOrgExtId("reseller", "myreseller"));
    theExt.addRemOrg(new EPPOrgExtId("privacyproxy", "myproxy"));

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand);
    System.out.println(theStats);

    // -- TEST5 - Test changing a reseller.
    theDomainCommand = new EPPDomainUpdateCmd("ABC-12345", "example.com", null, null, null);

    theExt = new EPPOrgExtUpdate();
    theExt.addChgOrg(new EPPOrgExtId("reseller", "myreseller"));

    theDomainCommand.addExtension(theExt);

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand);
    System.out.println(theStats);

    // -- TEST5 - Test changing multiple organizations
    theDomainCommand = new EPPDomainUpdateCmd("ABC-12345", "example.com", null, null, null);

    theExt = new EPPOrgExtUpdate();
    theExt.addChgOrg(new EPPOrgExtId("reseller", "myreseller"));
    theExt.addChgOrg(new EPPOrgExtId("privacyproxy", "myproxy"));

    theStats = EPPCodecTst.testEncodeDecode(theDomainCommand);
    System.out.println(theStats);

    EPPCodecTst.printEnd("testOrgExtUpdate");
  }

  /**
   * JUNIT <code>suite</code> static method, which returns the tests associated
   * with <code>EPPOrgExtTst</code>.
   */
  @BeforeClass
  public static void beforeClass() {
    EPPCodecTst.initEnvironment();

    // iterations Property
    String numIterProp = System.getProperty("iterations");

    if (numIterProp != null) {
      numIterations = Integer.parseInt(numIterProp);
    }

    // Add the EPPNSProductExtFactory to the EPPCodec.
    try {
      EPPFactory.getInstance().addMapFactory("com.verisign.epp.codec.host.EPPHostMapFactory");
      EPPFactory.getInstance().addMapFactory("com.verisign.epp.codec.domain.EPPDomainMapFactory");
      EPPFactory.getInstance().addExtFactory("com.verisign.epp.codec.orgext.EPPOrgExtFactory");
    }
    catch (EPPCodecException e) {
      Assert.fail("EPPCodecException adding factories to EPPCodec: " + e);
    }
  }

  /**
   * Sets the number of iterations to run per test.
   *
   * @param aNumIterations
   *           number of iterations to run per test
   */
  public static void setNumIterations(long aNumIterations) {
    numIterations = aNumIterations;
  }

}
