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

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.maintenance.v1_0.EPPMaintenanceDescription;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceId;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceInfoCmd;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceInfoResp;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceIntervention;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceItem;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceListItem;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceMapFactory;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceSystem;
import com.verisign.epp.codec.maintenance.v1_0.EPPMaintenanceType;
import com.verisign.epp.framework.EPPEvent;
import com.verisign.epp.framework.EPPEventResponse;
import com.verisign.epp.framework.EPPHandleEventException;
import com.verisign.epp.framework.EPPPollQueueException;
import com.verisign.epp.framework.EPPPollQueueMgr;
import com.verisign.epp.framework.v1_0.EPPMaintenanceHandler;

/**
 * The {@code MaintenanceHandler} class extends {@code EPPMaintenanceHandler} to
 * include handling the Maintenance Mapping commands.
 */
public class MaintenanceHandler extends EPPMaintenanceHandler {

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

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

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

		super.preHandleEvent(aEvent, aData);

	}

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

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

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

		EPPMaintenanceInfoResp theResp;

		if (theCommand.getInfoType() == EPPMaintenanceInfoCmd.InfoType.list) {

			theResp = new EPPMaintenanceInfoResp(theTransId);
			EPPMaintenanceListItem theItem = new EPPMaintenanceListItem(
			      new EPPMaintenanceId("2e6df9b0-4092-4491-bcc8-9fb2166dcee6"),
			      new GregorianCalendar(2021, 02, 8, 22, 10).getTime(),
			      new GregorianCalendar(2021, 04, 30, 6, 0).getTime(), new GregorianCalendar(2021, 04, 30, 7, 0).getTime(),
			      null);
			theResp.addListItem(theItem);
			theItem = new EPPMaintenanceListItem(new EPPMaintenanceId("91e9dabf-c4e9-4c19-a56c-78e3e89c2e2f"),
			      new GregorianCalendar(2021, 6, 15, 4, 30).getTime(), new GregorianCalendar(2021, 6, 15, 5, 30).getTime(),
			      new GregorianCalendar(2021, 02, 8, 22, 10).getTime(),
			      new GregorianCalendar(2021, 03, 8, 20, 11).getTime());
			theResp.addListItem(theItem);
		}
		else {
			EPPMaintenanceItem theMaintenance = new EPPMaintenanceItem();
			theMaintenance.setMaintenanceId(new EPPMaintenanceId(theCommand.getMaintenanceId()));
			theMaintenance.addType(new EPPMaintenanceType("Routine Maintenance"));
			theMaintenance
			      .addSystem(new EPPMaintenanceSystem("EPP", "epp.registry.example", EPPMaintenanceSystem.Impact.full));
			theMaintenance.setEnvironment(EPPMaintenanceItem.Environment.production);
			theMaintenance.setStartDate(new GregorianCalendar(2021, 9, 30, 6, 00).getTime());
			theMaintenance.setEndDate(new GregorianCalendar(2021, 9, 30, 14, 25, 57).getTime());
			theMaintenance.setReason(EPPMaintenanceItem.Reason.planned);
			theMaintenance.setDetail("https://www.registry.example/notice?123");
			theMaintenance.addDescription(new EPPMaintenanceDescription(
			      "<html>\n\t<head>\n\t\t<!-- head -->\n\t</head>\n\t<body>\n\t\t<!-- content -->\n\t</body>\n</html>",
			      EPPMaintenanceDescription.Type.html, EPPMaintenanceDescription.DEFAULT_LANG));
			theMaintenance.addTld("example");
			theMaintenance.addTld("test");
			theMaintenance.setIntervention(new EPPMaintenanceIntervention(false, false));
			theMaintenance.setCreatedDate(new GregorianCalendar(2021, 3, 8, 22, 10).getTime());

			theResp = new EPPMaintenanceInfoResp(theTransId, theMaintenance);

			if (theCommand.getMaintenanceId().equals("insert-maintenance-poll-msg")) {

				EPPMaintenanceInfoResp thePollResp = null;

				// Insert poll message
				try {
					EPPMaintenanceItem thePollItem = (EPPMaintenanceItem) theMaintenance.clone();
					thePollItem.setPollType(EPPMaintenanceItem.PollType.create);
					thePollResp = new EPPMaintenanceInfoResp(theTransId, thePollItem);

					EPPPollQueueMgr.getInstance().put(null, EPPMaintenanceMapFactory.NS, thePollResp, null);
				}
				catch (EPPPollQueueException | CloneNotSupportedException ex) {
					cat.error("doMaintenanceInfo: Error putting message [" + thePollResp + "]");

					EPPResult theResult = new EPPResult(EPPResult.COMMAND_FAILED);
					EPPResponse theResponse = new EPPResponse(theTransId, theResult);

					return new EPPEventResponse(theResponse);
				}

			}

		}

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

}
