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

import java.util.Date;
import java.util.Vector;

import com.verisign.epp.codec.contact.EPPContactAddress;
import com.verisign.epp.codec.contact.EPPContactCreateCmd;
import com.verisign.epp.codec.contact.EPPContactDisclose;
import com.verisign.epp.codec.contact.EPPContactInfoResp;
import com.verisign.epp.codec.contact.EPPContactPostalDefinition;
import com.verisign.epp.codec.contact.EPPContactStatus;
import com.verisign.epp.codec.contact.EPPContactUpdateCmd;
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 supporting the Additional Email Extension.
 */
public class EPPAddlEmailTst {
  /**
   * Number of unit test iterations to run. This is set in
   * {@code EPPCodecTst.main}
   */
  static private long numIterations = 1;

  /**
   * Unit test of passing an EAI address in a [RFC5733] contact create command and an ASCII alternate address.
   */
  @Test
  public void testContactCreateASCIIAlternate() {
    EPPContactCreateCmd theCommand;
    EPPEncodeDecodeStats commandStats;

    EPPCodecTst.printStart("testContactCreateASCIIAlternate");

    // Streets
    Vector streets = new Vector();
    streets.addElement("123 Example Dr.");
    streets.addElement("Suite 100");

    // Address
    EPPContactAddress address = new EPPContactAddress(streets, "Dulles", "VA", "20166-6503", "US");

    // Postal Definition
    EPPContactPostalDefinition postalInfo = new EPPContactPostalDefinition("John Doe", "Example Inc.",
          EPPContactPostalDefinition.ATTR_TYPE_INT, address);

    // Contact Command
    theCommand = new EPPContactCreateCmd("ABC-123451", "sh8013", postalInfo, "jdoe@example.com", new EPPAuthInfo("2fooBAR"));
    theCommand.setVoice("+1.7035555555");
    theCommand.setVoiceExt("1234");
    theCommand.setFax("+1.7035555556");

    // Add ASCII alternate email 
    theCommand.addExtension(new EPPAddlEmail("jdoe-alternate@example.com"));

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

    EPPCodecTst.printEnd("testContactCreateASCIIAlternate");
  }

  /**
   * Unit test of passing an EAI address in a [RFC5733] contact create command and an SMTPUTF8 alternate address.
   */
  @Test
  public void testContactCreateSMTPUTF8Primary() {
    EPPContactCreateCmd theCommand;
    EPPEncodeDecodeStats commandStats;

    EPPCodecTst.printStart("testContactCreateSMTPUTF8Primary");

    // Streets
    Vector streets = new Vector();
    streets.addElement("123 Example Dr.");
    streets.addElement("Suite 100");

    // Address
    EPPContactAddress address = new EPPContactAddress(streets, "Dulles", "VA", "20166-6503", "US");

    // Postal Definition
    EPPContactPostalDefinition postalInfo = new EPPContactPostalDefinition("John Doe", "Example Inc.",
          EPPContactPostalDefinition.ATTR_TYPE_INT, address);

    // Contact Command
    theCommand = new EPPContactCreateCmd("ABC-123451", "sh8013", postalInfo, "jdoe@example.com", new EPPAuthInfo("2fooBAR"));
    theCommand.setVoice("+1.7035555555");
    theCommand.setVoiceExt("1234");
    theCommand.setFax("+1.7035555556");

    // Add ASCII alternate email 
    theCommand.addExtension(new EPPAddlEmail("麥克風@example.com", true));

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

    EPPCodecTst.printEnd("testContactCreateSMTPUTF8Primary");
  }

  /**
   * Unit test of passing an ASCII email in the extension to an [RFC5733] contact update
   * command.
   */
  @Test
  public void testContactUpdateASCIIAlternate() {
    EPPContactUpdateCmd theCommand = null;
    EPPEncodeDecodeStats commandStats = null;

    EPPCodecTst.printStart("testContactUpdateASCIIAlternate");

    // Update Command
    theCommand = new EPPContactUpdateCmd("ABC-123452", "sh8013", null, null, null);

    // Set ASCII alternate email 
    theCommand.addExtension(new EPPAddlEmail("jdoe-alternate@example.com"));    

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

    EPPCodecTst.printEnd("testContactUpdateASCIIAlternate");
  }

  /**
   * Unit test of passing an SMTPUTF8 email in the extension to an [RFC5733] contact update
   * command.
   */
  @Test
  public void testContactUpdateSMTPUTF8Alternate() {
    EPPContactUpdateCmd theCommand = null;
    EPPEncodeDecodeStats commandStats = null;

    EPPCodecTst.printStart("testContactUpdateSMTPUTF8Alternate");

    // Update Command
    theCommand = new EPPContactUpdateCmd("ABC-123452", "sh8013", null, null, null);

    // Set ASCII alternate email 
    theCommand.addExtension(new EPPAddlEmail("麥克風@example.com"));    

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

    EPPCodecTst.printEnd("testContactUpdateSMTPUTF8Alternate");
  }

  /**
   * Unit test of unsetting the alternate email in the extension to an [RFC5733] contact update
   * command.
   */
  @Test
  public void testContactUpdateUnsetAlternate() {
    EPPContactUpdateCmd theCommand = null;
    EPPEncodeDecodeStats commandStats = null;

    EPPCodecTst.printStart("testContactUpdateUnsetAlternate");

    // Update Command
    theCommand = new EPPContactUpdateCmd("ABC-123452", "sh8013", null, null, null);

    // Set ASCII alternate email 
    theCommand.addExtension(new EPPAddlEmail());    

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

    EPPCodecTst.printEnd("testContactUpdateUnsetAlternate");
  }

  /**
   * Unit test of returning an ASCII email in the extension to an [RFC5733] contact info response. 
   */
  @Test
  public void testContactInfoRespASCIIAlternate() {
    EPPContactInfoResp theResponse = null;
    EPPEncodeDecodeStats responseStats = null;

    EPPCodecTst.printStart("testContactInfoRespASCIIAlternate");

    // Streets
    Vector streets = new Vector();
    streets.addElement("123 Example Dr.");
    streets.addElement("Suite 100");

    // Address
    EPPContactAddress address = new EPPContactAddress(streets, "Dulles", "VA", "20166-6503", "US");

    // Name Postal Definition
    EPPContactPostalDefinition name = new EPPContactPostalDefinition("John Doe", "Example Inc.",
          EPPContactPostalDefinition.ATTR_TYPE_INT, address);

    // infoStatuses
    Vector infoStatuses = new Vector();
    infoStatuses.addElement(new EPPContactStatus(EPPContactStatus.ELM_STATUS_LINKED));
    infoStatuses.addElement(new EPPContactStatus(EPPContactStatus.ELM_STATUS_CLIENT_UPDATE_PROHIBITED));

    // Test with just required EPPContactInfoResp attributes.
    EPPTransId respTransId = new EPPTransId("ABC-12345", "54321-XYZ");
    theResponse = new EPPContactInfoResp(respTransId, "SH8013-REP", "sh8013", infoStatuses, name, "jdoe@example.com",
          "ClientY", "ClientX", new Date(), new EPPAuthInfo("2fooBAR"));

    theResponse.setVoice("+1.7035555555");
    theResponse.setVoiceExt("1234");
    theResponse.setFax("+1.7035555556");

    // disclose
    EPPContactDisclose disclose = new EPPContactDisclose(true, true, false, true, true, true, true, true, true, true);

    theResponse.setDisclose(disclose);

    theResponse.setResult(EPPResult.SUCCESS);

    theResponse.setLastUpdatedBy("ClientX");
    theResponse.setLastUpdatedDate(new Date());
    theResponse.setLastTransferDate(new Date());

    // Set alternate ASCII alternate email 
    theResponse.addExtension(new EPPAddlEmail("jdoe-alternate@example.com"));   

    responseStats = EPPCodecTst.testEncodeDecode(theResponse);
    System.out.println(responseStats);

    EPPCodecTst.printEnd("testContactInfoRespASCIIAlternate");  }

  /**
   * Unit test of returning an SMTPUTF8 email in the extension to an [RFC5733] contact info response.
   */
  @Test
  public void testContactInfoResponseSMTPUTF8Primary() {
    EPPContactInfoResp theResponse = null;
    EPPEncodeDecodeStats responseStats = null;

    EPPCodecTst.printStart("testContactInfoResponseSMTPUTF8Primary");

    // Streets
    Vector streets = new Vector();
    streets.addElement("123 Example Dr.");
    streets.addElement("Suite 100");

    // Address
    EPPContactAddress address = new EPPContactAddress(streets, "Dulles", "VA", "20166-6503", "US");

    // Name Postal Definition
    EPPContactPostalDefinition name = new EPPContactPostalDefinition("John Doe", "Example Inc.",
          EPPContactPostalDefinition.ATTR_TYPE_INT, address);

    // infoStatuses
    Vector infoStatuses = new Vector();
    infoStatuses.addElement(new EPPContactStatus(EPPContactStatus.ELM_STATUS_LINKED));
    infoStatuses.addElement(new EPPContactStatus(EPPContactStatus.ELM_STATUS_CLIENT_UPDATE_PROHIBITED));

    // Test with just required EPPContactInfoResp attributes.
    EPPTransId respTransId = new EPPTransId("ABC-12345", "54321-XYZ");
    theResponse = new EPPContactInfoResp(respTransId, "SH8013-REP", "sh8013", infoStatuses, name, "jdoe@example.com",
          "ClientY", "ClientX", new Date(), new EPPAuthInfo("2fooBAR"));

    theResponse.setVoice("+1.7035555555");
    theResponse.setVoiceExt("1234");
    theResponse.setFax("+1.7035555556");

    // disclose
    EPPContactDisclose disclose = new EPPContactDisclose(true, true, false, true, true, true, true, true, true, true);

    theResponse.setDisclose(disclose);

    theResponse.setResult(EPPResult.SUCCESS);

    theResponse.setLastUpdatedBy("ClientX");
    theResponse.setLastUpdatedDate(new Date());
    theResponse.setLastTransferDate(new Date());

    // Set empty ASCII alternate email 
    theResponse.addExtension(new EPPAddlEmail("麥克風@example.com", true));

    responseStats = EPPCodecTst.testEncodeDecode(theResponse);
    System.out.println(responseStats);

    EPPCodecTst.printEnd("testContactInfoResponseSMTPUTF8Primary");
  }

  /**
   * Unit test of returning an empty alternative email in the extension to an [RFC5733] contact info response.
   */
  @Test
  public void testContactInfoRespUnsetAlternate() {
    EPPContactInfoResp theResponse = null;
    EPPEncodeDecodeStats responseStats = null;

    EPPCodecTst.printStart("testContactInfoRespUnsetAlternate");

    // Streets
    Vector streets = new Vector();
    streets.addElement("123 Example Dr.");
    streets.addElement("Suite 100");

    // Address
    EPPContactAddress address = new EPPContactAddress(streets, "Dulles", "VA", "20166-6503", "US");

    // Name Postal Definition
    EPPContactPostalDefinition name = new EPPContactPostalDefinition("John Doe", "Example Inc.",
          EPPContactPostalDefinition.ATTR_TYPE_INT, address);

    // infoStatuses
    Vector infoStatuses = new Vector();
    infoStatuses.addElement(new EPPContactStatus(EPPContactStatus.ELM_STATUS_LINKED));
    infoStatuses.addElement(new EPPContactStatus(EPPContactStatus.ELM_STATUS_CLIENT_UPDATE_PROHIBITED));

    // Test with just required EPPContactInfoResp attributes.
    EPPTransId respTransId = new EPPTransId("ABC-12345", "54321-XYZ");
    theResponse = new EPPContactInfoResp(respTransId, "SH8013-REP", "sh8013", infoStatuses, name, "jdoe@example.com",
          "ClientY", "ClientX", new Date(), new EPPAuthInfo("2fooBAR"));

    theResponse.setVoice("+1.7035555555");
    theResponse.setVoiceExt("1234");
    theResponse.setFax("+1.7035555556");

    // disclose
    EPPContactDisclose disclose = new EPPContactDisclose(true, true, false, true, true, true, true, true, true, true);

    theResponse.setDisclose(disclose);

    theResponse.setResult(EPPResult.SUCCESS);

    theResponse.setLastUpdatedBy("ClientX");
    theResponse.setLastUpdatedDate(new Date());
    theResponse.setLastTransferDate(new Date());

    // Set empty ASCII alternate email 
    theResponse.addExtension(new EPPAddlEmail());   

    responseStats = EPPCodecTst.testEncodeDecode(theResponse);
    System.out.println(responseStats);

    EPPCodecTst.printEnd("testContactInfoRespUnsetAlternate");
  }

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

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

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

    // Add map factories the EPPCodec.
    try {
      EPPFactory.getInstance().addMapFactory("com.verisign.epp.codec.contact.EPPContactMapFactory");
      EPPFactory.getInstance().addExtFactory("com.verisign.epp.codec.addlemail.EPPAddlEmailExtFactory");
    }
    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;
  }

}
