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

import java.util.GregorianCalendar;

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.EPPTransId;
import com.verisign.epp.util.TestThread;

import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Is a unit test of the com.verisign.epp.codec.org package.
 */
public class EPPOrgTst extends TestCase {
	/**
	 * Number of unit test iterations to run. This is set in
	 * <code>EPPCodecTst.main</code>
	 */
	static private long numIterations = 1;

	/**
	 * Creates a new EPPOrgTst object.
	 *
	 * @param name
	 *           Name of test
	 */
	public EPPOrgTst(String name) {
		super(name);
	}

	/**
	 * Unit test of the Org Check Command. The following are the tests:<br>
	 * <ol>
	 * <li>TEST1 - Check an individual org identifier.</li>
	 * <li>TEST2 - Check three org identifiers.</li>
	 * </ol>
	 */
	public void testCheckCommand() {
		EPPCodecTst.printStart("testCheckCommand");

		EPPEncodeDecodeStats theStats;

		// TEST1 - Check an individual org identifier.
		EPPOrgCheckCmd theCommand = new EPPOrgCheckCmd("ABC-12345", "res1523");

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

		// TEST2 - Check three org identifiers.
		theCommand = new EPPOrgCheckCmd("ABC-12345");

		theCommand.addOrgId("res1523");
		theCommand.addOrgId("re1523");
		theCommand.addOrgId("1523res");

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

		EPPCodecTst.printEnd("testCheckCommand");
	}

	/**
	 * Unit test of the Org Check Response. The following are the tests:<br>
	 * <ol>
	 * <li>TEST1 - Check response with an individual result.</li>
	 * <li>TEST2 - Check response with three results.</li>
	 * </ol>
	 */
	public void testCheckResponse() {
		EPPCodecTst.printStart("testCheckResponse");

		EPPEncodeDecodeStats theStats;

		EPPTransId theTransId = new EPPTransId("ABC-12345", "54321-XYZ");

		// TEST1 - Check response with an individual result.
		EPPOrgCheckResp theResp = new EPPOrgCheckResp(theTransId, new EPPOrgCheckResult("res1523", true));

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

		// TEST2 - Check response with three results.
		theResp = new EPPOrgCheckResp(theTransId);

		theResp.addCheckResult(new EPPOrgCheckResult("res1523", true));
		theResp.addCheckResult(new EPPOrgCheckResult("re1523", "In use"));
		theResp.addCheckResult(new EPPOrgCheckResult("1523res", true));

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

		EPPCodecTst.printEnd("testCheckResponse");
	}

	/**
	 * Unit test of the Org Info Command.
	 */
	public void testInfoCommand() {
		EPPCodecTst.printStart("testInfoCommand");

		EPPEncodeDecodeStats theStats;

		EPPOrgInfoCmd theCommand = new EPPOrgInfoCmd("ABC-12345", "res1523");

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

		EPPCodecTst.printEnd("testInfoCommand");
	}

	/**
	 * Unit test of the Org Info Response.
	 */
	public void testInfoResponse() {
		EPPCodecTst.printStart("testInfoResponse");

		EPPEncodeDecodeStats theStats;

		EPPTransId theTransId = new EPPTransId("ABC-12345", "54321-XYZ");

		// TEST - Registrar organization
		EPPOrgInfoResp theResp = new EPPOrgInfoResp(theTransId, "registrar1362");
		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());

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

		// TEST - Registrar organization
		theResp = new EPPOrgInfoResp(theTransId, "reseller1523");
		theResp.setRoid("reseller1523-REP");
		EPPOrgRole theRole = new EPPOrgRole("reseller");
		theRole.addStatus(EPPOrgRoleStatus.ok);
		theRole.addStatus(EPPOrgRoleStatus.linked);
		theResp.addRole(theRole);
		theResp.addStatus(EPPOrgStatus.ok);
		theResp.setParentId("registrar1362");

		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 Reseller Inc.", theAddress));
		theResp.setFax("+1.7035555556");
		theResp.setUrl("http://organization.example");
		theResp.addContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.ADMINISTRATIVE));
		theResp.setClientId("1362");
		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());

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

		EPPCodecTst.printEnd("testInfoResponse");
	}

	/**
	 * Unit test of the Org Create Command.
	 */
	public void testCreateCommand() {
		EPPCodecTst.printStart("testCreateCommand");

		EPPEncodeDecodeStats theStats;

		EPPOrgCreateCmd theCommand = new EPPOrgCreateCmd();

		theCommand.setOrgId("res1523");

		theCommand.addRole(new EPPOrgRole("reseller", EPPOrgRoleStatus.ok, null));
		theCommand.addRole(new EPPOrgRole("privacyproxy", EPPOrgRoleStatus.ok, null));
		theCommand.addStatus(EPPOrgStatus.clientLinkProhibited);

		theCommand.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");

		theCommand.addPostalInfo(
		      new EPPOrgPostalDefinition(EPPOrgPostalDefinition.Type.INT, "Example Organization Inc.", theAddress));
		theCommand.setVoice("+1.7035555555");
		theCommand.setVoiceExt("1234");
		theCommand.setFax("+1.7035555556");
		theCommand.setEmail("contact@organization.example");
		theCommand.setUrl("http://organization.example");
		theCommand.addContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.ADMINISTRATIVE));
		theCommand.addContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.BILLING));

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

		EPPCodecTst.printEnd("testCreateCommand");
	}

	/**
	 * Unit test of the Org Create Response.
	 */
	public void testCreateResponse() {
		EPPCodecTst.printStart("testCreateResponse");

		EPPEncodeDecodeStats theStats;

		EPPTransId theTransId = new EPPTransId("ABC-12345", "54321-XYZ");

		EPPOrgCreateResp theResp = new EPPOrgCreateResp(theTransId, "res1523",
		      new GregorianCalendar(1999, 04, 03, 22, 0).getTime());

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

		EPPCodecTst.printEnd("testCreateResponse");
	}

	/**
	 * Unit test of the Org Delete Command.
	 */
	public void testDeleteCommand() {
		EPPCodecTst.printStart("testDeleteCommand");

		EPPEncodeDecodeStats theStats;

		EPPOrgDeleteCmd theCommand = new EPPOrgDeleteCmd("ABC-12345", "res1523");

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

		EPPCodecTst.printEnd("testDeleteCommand");
	}

	/**
	 * Unit test of the Org Update Command.
	 */
	public void testUpdateCommand() {
		EPPCodecTst.printStart("testUpdateCommand");

		EPPEncodeDecodeStats theStats;

		EPPOrgUpdateCmd theCommand = new EPPOrgUpdateCmd();

		theCommand.setOrgId("res1523");

		// Add section
		theCommand.addAddContact(new EPPOrgContact("sh8013", EPPOrgContact.Type.TECHNICAL));
		theCommand.addAddRole(new EPPOrgRole("privacyproxy", EPPOrgRoleStatus.clientLinkProhibited, null));
		theCommand.addAddStatus(EPPOrgStatus.clientLinkProhibited);

		// Delete section
		theCommand.addRemContact(new EPPOrgContact("sh8014", EPPOrgContact.Type.BILLING));
		theCommand.addRemRole(new EPPOrgRole("reseller"));
		theCommand.addRemStatus(EPPOrgStatus.clientDeleteProhibited);

		theCommand.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");

		EPPOrgPostalDefinition thePostalDef = new EPPOrgPostalDefinition(EPPOrgPostalDefinition.Type.INT);
		thePostalDef.setAddress(theAddress);

		theCommand.addPostalInfo(thePostalDef);

		theCommand.setVoice("+1.7034444444");

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

		EPPCodecTst.printEnd("testUpdateCommand");
	}

	/**
	 * JUNIT <code>setUp</code> method, which sets the default client Id to
	 * "theRegistrar" and initializes the <code>EPPOrgMapFactory</code> with the
	 * <code>EPPCodec</code>.
	 */
	protected void setUp() {
	}

	/**
	 * JUNIT <code>tearDown</code>, which currently does nothing.
	 */
	protected void tearDown() {
	}

	/**
	 * JUNIT <code>suite</code> static method, which returns the tests associated
	 * with <code>EPPOrgTst</code>.
	 *
	 * @return Tests to run
	 */
	public static Test suite() {
		EPPCodecTst.initEnvironment();

		TestSuite suite = new TestSuite(EPPOrgTst.class);

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

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

		// Add the EPPOrgMapFactory to the EPPCodec.
		try {
			EPPFactory.getInstance().addMapFactory("com.verisign.epp.codec.org.EPPOrgMapFactory");
		}
		catch (EPPCodecException e) {
			Assert.fail("EPPCodecException adding factories to EPPCodec: " + e);
		}

		return suite;
	}

	/**
	 * Unit test main, which accepts the following system property options:<br>
	 * 
	 * <ul>
	 * <li>iterations Number of unit test iterations to run</li>
	 * <li>validate Turn XML validation on (<code>true</code>) or off (
	 * <code>false</code>). If validate is not specified, validation will be off.
	 * </li>
	 * </ul>
	 *
	 * @param args
	 *           Program arguments
	 */
	public static void main(String[] args) {
		// Number of Threads
		int numThreads = 1;
		String threadsStr = System.getProperty("threads");

		if (threadsStr != null) {
			numThreads = Integer.parseInt(threadsStr);
		}

		// Run test suite in multiple threads?
		if (numThreads > 1) {
			// Spawn each thread passing in the Test Suite
			for (int i = 0; i < numThreads; i++) {
				TestThread thread = new TestThread("EPPOrgTst Thread " + i, EPPOrgTst.suite());
				thread.start();
			}
		}
		else { // Single threaded mode.
			junit.textui.TestRunner.run(EPPOrgTst.suite());
		}
	}

	/**
	 * 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;
	}

}
