/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.core.client;

import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSServerException;

/**
 * Abstract base class for requests that are to be sent to the server.
 */
public abstract class Request {
	public static final ExpandModules EXPAND_MODULES = new ExpandModules();
	public static final ValidRequests VALID_REQUESTS = new ValidRequests();

	/*** Response handler map ***/
	private static final Map responseHandlers = new HashMap();
	
	private static void initializeHandlerCache() {
		synchronized(responseHandlers) {
			registerResponseHandler(new CheckedInHandler());
			registerResponseHandler(new CopyHandler());
			registerResponseHandler(new ModTimeHandler());
			registerResponseHandler(new NewEntryHandler());
			registerResponseHandler(new RemovedHandler());
			registerResponseHandler(new RemoveEntryHandler());
			registerResponseHandler(new StaticHandler(true));
			registerResponseHandler(new StaticHandler(false));
			registerResponseHandler(new StickyHandler(true));
			registerResponseHandler(new StickyHandler(false));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_UPDATED));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_UPDATE_EXISTING));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_CREATED));
			registerResponseHandler(new UpdatedHandler(UpdatedHandler.HANDLE_MERGED));
			registerResponseHandler(new ValidRequestsHandler());
			registerResponseHandler(new ModuleExpansionHandler());
			registerResponseHandler(new MTHandler());
			registerResponseHandler(new NotifiedHandler());
			registerResponseHandler(new TemplateHandler());
		}
	}
	private static void registerResponseHandler(ResponseHandler handler) {
		synchronized(responseHandlers) {
			responseHandlers.put(handler.getResponseID(), handler);
		}
	}
	
	/**
	 * This method is invoked by Session to get a mutable copy of the
	 * global list of acceptable response handlers.
	 * 
	 * @return a map of response handlers
	 */
	protected static Map getReponseHandlerMap() {
		synchronized(responseHandlers) {
			if (responseHandlers.isEmpty()) {
				initializeHandlerCache();
			}
			Map copy = new HashMap();
			for (Iterator iter = responseHandlers.values().iterator(); iter.hasNext();) {
				ResponseHandler handler = (ResponseHandler) iter.next();
				copy.put(handler.getResponseID(), handler.getInstance());
				
			}
			return copy;
		}
	}
	/**
	 * Prevents client code from instantiating us.
	 */
	protected Request() { }

	/**
	 * Returns the string used to invoke this request on the server.
	 * [template method]
	 * 
	 * @return the request identifier string
	 */
	protected abstract String getRequestId();

	/**
	 * Executes a request and processes the responses.
	 * 
	 * @param session the open CVS session
	 * @param listener the command output listener, or null to discard all messages
	 * @param monitor the progress monitor
	 * @return a status code indicating success or failure of the operation
	 */
	protected IStatus executeRequest(Session session, ICommandOutputListener listener,
		IProgressMonitor monitor) throws CVSException {
		// send request
		session.sendRequest(getRequestId());

		// This number can be tweaked if the monitor is judged to move too
		// quickly or too slowly. After some experimentation this is a good
		// number for both large projects (it doesn't move so quickly as to
		// give a false sense of speed) and smaller projects (it actually does
		// move some rather than remaining still and then jumping to 100).
		final int TOTAL_WORK = 300;
		monitor.beginTask(CVSMessages.Command_receivingResponses, TOTAL_WORK); 
		monitor.subTask(CVSMessages.Command_receivingResponses); 
		int halfWay = TOTAL_WORK / 2;
		int currentIncrement = 4;
		int nextProgress = currentIncrement;
		int worked = 0;
		
		// If the session is connected to a CVSNT server (1.11.1.1), we'll need to do some special handling for
		// some errors. Unfortunately, CVSNT 1.11.1.1 will drop the connection after so some functionality is
		// still affected
		boolean isCVSNT = session.isCVSNT();

		session.clearErrors();
		for (;;) {
			// update monitor work amount
			if (--nextProgress <= 0) {
				monitor.worked(1);
				worked++;
				if (worked >= halfWay) {
					// we have passed the current halfway point, so double the
					// increment and reset the halfway point.
					currentIncrement *= 2;
					halfWay += (TOTAL_WORK - halfWay) / 2;				
				}
				// reset the progress counter to another full increment
				nextProgress = currentIncrement;
			}			
			Policy.checkCanceled(monitor);

			// retrieve a response line
			String response = session.readLine();
			int spacePos = response.indexOf(' ');
			String argument;
			if (spacePos != -1) {
				argument = response.substring(spacePos + 1);
				response = response.substring(0, spacePos);
			} else argument = "";  //$NON-NLS-1$

			// handle completion responses
			if (response.equals("ok")) {  //$NON-NLS-1$
				break;
			} else if (response.equals("error") || (isCVSNT && response.equals(""))) {  //$NON-NLS-1$ //$NON-NLS-2$
				argument = argument.trim();
				boolean serious = false;
				if (argument.length() == 0) {
					argument = getServerErrorMessage();
				} else {
					argument = NLS.bind(CVSMessages.Command_seriousServerError, new String[] { argument }); 
					if (!session.hasErrors()) {
						session.addError(new CVSStatus(IStatus.ERROR, CVSStatus.SERVER_ERROR, argument,session.getLocalRoot()));
					}
					serious = true;
				}
					
				if (!session.hasErrors()) {
					session.addError(new CVSStatus(IStatus.ERROR, CVSStatus.SERVER_ERROR, CVSMessages.Command_noMoreInfoAvailable,session.getLocalRoot()));
				}
				IStatus status = new MultiStatus(CVSProviderPlugin.ID, CVSStatus.SERVER_ERROR, 
						session.getErrors(),
					argument, null);
				if (serious) {
					throw new CVSServerException(status);
				} else {
					// look for particularly bad errors in the accumulated statuses
					IStatus[] errors = session.getErrors();
					for (int i = 0; i < errors.length; i++) {
						IStatus s = errors[i];
						if (s.getCode() == CVSStatus.PROTOCOL_ERROR) {
							throw new CVSServerException(status);
						}
					}
				}
				return status;
			// handle message responses
			} else if (response.equals("MT")) {  //$NON-NLS-1$
				// Handle the MT response
				MTHandler handler = (MTHandler) session.getResponseHandler(response);
				if (handler != null) {
					handler.handle(session, argument, monitor);
				} else {
					throw new CVSException(new org.eclipse.core.runtime.Status(IStatus.ERROR,
						CVSProviderPlugin.ID, TeamException.IO_FAILED,
						NLS.bind(CVSMessages.Command_unsupportedResponse, new String[] { response, argument }), null)); 
				}
				// If a line is available, pass it on to the message listener 
				// and console as if it were an M response
				if (handler.isLineAvailable()) {
					String line = handler.getLine();
					IStatus status = listener.messageLine(line, session.getCVSRepositoryLocation(), session.getLocalRoot(), monitor);
					session.addError(status); // The session ignores OK status
					ConsoleListeners.getInstance().messageLineReceived(session, line, status);

				}
			} else if (response.equals("M")) {  //$NON-NLS-1$
				IStatus status = listener.messageLine(argument, session.getCVSRepositoryLocation(), session.getLocalRoot(), monitor);
				session.addError(status); // The session ignores OK status
				ConsoleListeners.getInstance().messageLineReceived(session, argument, status);
			} else if (response.equals("E")) { //$NON-NLS-1$
				IStatus status = listener.errorLine(argument, session.getCVSRepositoryLocation(), session.getLocalRoot(), monitor);
				session.addError(status); // The session ignores OK status
				ConsoleListeners.getInstance().errorLineReceived(session, argument, status);
			// handle other responses
			} else {
				ResponseHandler handler = session.getResponseHandler(response);
				if (handler != null) {
					handler.handle(session, argument, monitor);
				} else {
					throw new CVSException(new org.eclipse.core.runtime.Status(IStatus.ERROR,
						CVSProviderPlugin.ID, TeamException.IO_FAILED,
						NLS.bind(CVSMessages.Command_unsupportedResponse, new String[] { response, argument }), null)); 
				}
			}
		}
		if (!session.hasErrors()) {
			return ICommandOutputListener.OK;
		} else {
			return new MultiStatus(CVSProviderPlugin.ID, IStatus.INFO,
				session.getErrors(),
				NLS.bind(CVSMessages.Command_warnings, new String[] { getDisplayText() }), null);
		}
	}
	
	/*
	 * Provide the message that is used for the status that is generated when the server
	 * reports as error.
	 */
	protected String getServerErrorMessage() {
		return NLS.bind(CVSMessages.Command_serverError, new String[] { getDisplayText() });
	}
	protected String getDisplayText() {
		return getRequestId();
	}
}
