/*******************************************************************************
 * Copyright (c) 2000, 2014 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.listeners;

import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSStatus;
import org.eclipse.team.internal.ccvs.core.ICVSFile;
import org.eclipse.team.internal.ccvs.core.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.client.CommandOutputListener;
import org.eclipse.team.internal.ccvs.core.client.Update;
import org.eclipse.team.internal.ccvs.core.util.Util;

public class UpdateListener extends CommandOutputListener {

	// Pattern matchers
	private static ServerMessageLineMatcher MERGED_BINARY_FILE_LINE_1;
	private static ServerMessageLineMatcher MERGED_BINARY_FILE_LINE_2;
	
	// Pattern Variables
	private static final String REVISION_VARIABLE_NAME = "revision"; //$NON-NLS-1$
	private static final String LOCAL_FILE_PATH_VARIABLE_NAME = "localFilePath"; //$NON-NLS-1$
	private static final String BACKUP_FILE_VARIABLE_NAME = "backupFile"; //$NON-NLS-1$
	
	static {
		try {
			String line1 = "revision " //$NON-NLS-1$
				+ Util.getVariablePattern(IMessagePatterns.REVISION_PATTERN, REVISION_VARIABLE_NAME)
				+ " from repository is now in "  //$NON-NLS-1$
				+ Util.getVariablePattern(IMessagePatterns.FILE_PATH_PATTERN, LOCAL_FILE_PATH_VARIABLE_NAME);
			MERGED_BINARY_FILE_LINE_1 = new ServerMessageLineMatcher(
					line1, 
					new String[] {REVISION_VARIABLE_NAME, LOCAL_FILE_PATH_VARIABLE_NAME});
			String line2 = "file from working directory is now in " //$NON-NLS-1$
				+ Util.getVariablePattern(IMessagePatterns.REVISION_PATTERN, BACKUP_FILE_VARIABLE_NAME);
			MERGED_BINARY_FILE_LINE_2 = new ServerMessageLineMatcher(
					line2, 
					new String[] {BACKUP_FILE_VARIABLE_NAME});

		} catch (CVSException e) {
			// Shouldn't happen
			CVSProviderPlugin.log(e);
		}
	}
	
	IUpdateMessageListener updateMessageListener;
	boolean merging = false;
	boolean mergingBinary = false;
	String mergedBinaryFileRevision, mergedBinaryFilePath;

	public UpdateListener(IUpdateMessageListener updateMessageListener) {
		this.updateMessageListener = updateMessageListener;
	}
	
	public IStatus messageLine(String line, ICVSRepositoryLocation location, ICVSFolder commandRoot,
		IProgressMonitor monitor) {
		mergingBinary = false;
		if (updateMessageListener == null) return OK;
		if(line.startsWith("Merging differences")) { //$NON-NLS-1$
			merging = true;
		} else if(line.indexOf(' ')==1) {
			// We have a message that indicates the type of update. The possible messages are
			// defined by the prefix constants MLP_*.
			String path = line.substring(2);
			char changeType = line.charAt(0);
			
			// calculate change type
			int type = 0;
			switch(changeType) {
				case 'A': type = Update.STATE_ADDED_LOCAL; break; // new file locally that was added but not comitted to server yet
				case '?': type = Update.STATE_UNKOWN; break; // new file locally but not added to server
				case 'U': type = Update.STATE_REMOTE_CHANGES; break;  // remote changes to an unmodified local file
				case 'R': type = Update.STATE_DELETED; break; // removed locally but still exists on the server
				case 'M': type = Update.STATE_MODIFIED; break; // modified locally
				case 'C': type = Update.STATE_CONFLICT; break;  // modified locally and on the server but cannot be auto-merged
				case 'D': type = Update.STATE_DELETED; break;  // deleted locally but still exists on server
				default: type = Update.STATE_NONE;
			}
				
			if (merging) {
				// If we are merging the modified prefix is used both to show merges and
				// local changes. We have to detect this case and use a more specific change
				// type.
				if (type == Update.STATE_MODIFIED)
					type = Update.STATE_MERGEABLE_CONFLICT;
				merging = false;
			}
			updateMessageListener.fileInformation(type, commandRoot, path);
		}
		return OK;
	}

	/**
	 * This handler is used by the RemoteResource hierarchy to retrieve E messages
	 * from the CVS server in order to determine the folders contained in a parent folder.
	 * 
	 * WARNING: This class parses the message output to determine the state of files in the
	 * repository. Unfortunately, these messages seem to be customizable on a server by server basis.
	 * 
	 * Here's a list of responses we expect in various situations:
	 * 
	 * Directory exists remotely:
	 *    cvs server: Updating folder1/folder2
	 * Directory doesn't exist remotely:
	 *    cvs server: skipping directory folder1/folder2
	 * New (or unknown) remote directory
	 *    cvs server: New Directory folder1/folder2
	 * File removed remotely
	 *    cvs server: folder1/file.ext is no longer in the repository
	 *    cvs server: warning: folder1/file.ext is not (any longer) pertinent
	 * Locally added file was added remotely as well
	 *    cvs server: conflict: folder/file.ext created independently by second party 
	 * File removed locally and modified remotely
	 *    cvs server: conflict: removed file.txt was modified by second party
	 * File modified locally but removed remotely
	 *    cvs server: conflict: file.txt is modified but no longer in the repository
	 * Ignored Messages
	 *    cvs server: cannot open directory ...
	 *    cvs server: nothing known about ...
	 * Tag error that really means there are no files in a directory
	 *    cvs [server aborted]: no such tag
	 * Merge contained conflicts
	 *    rcsmerge: warning: conflicts during merge
	 * Binary file conflict
	 *    cvs server: nonmergeable file needs merge
	 *    cvs server: revision 1.4 from repository is now in a1/a2/test
	 *    cvs server: file from working directory is now in .#test.1.3
	 */
	public IStatus errorLine(String line, ICVSRepositoryLocation location, ICVSFolder commandRoot,
		IProgressMonitor monitor) {
		
		try {
			// Reset flag globally here because we have to many exit points
			boolean wasMergingBinary = mergingBinary;
			mergingBinary = false;
			String serverMessage = getServerMessage(line, location);
			if (serverMessage != null) {
				// Strip the prefix from the line
				String message = serverMessage;
				if (message.startsWith("Updating")) { //$NON-NLS-1$
					if (updateMessageListener != null) {
						String path = message.substring(9);
						updateMessageListener.directoryInformation(commandRoot, path, false);
					}
					return OK;
				} else if (message.startsWith("skipping directory")) { //$NON-NLS-1$
					if (updateMessageListener != null) {
						String path = message.substring(18).trim();
						updateMessageListener.directoryDoesNotExist(commandRoot, path);
					}
					return OK;
				} else if (message.startsWith("New directory")) { //$NON-NLS-1$
					if (updateMessageListener != null) {
						String path = message.substring(15, message.lastIndexOf('\''));
						updateMessageListener.directoryInformation(commandRoot, path, true);
					}
					return OK;
				} else if (message.endsWith("is no longer in the repository")) { //$NON-NLS-1$
					if (updateMessageListener != null) {
						String filename = message.substring(0, message.length() - 31);
						filename = stripQuotes(filename);
						updateMessageListener.fileDoesNotExist(commandRoot, filename);
					}
					return OK;
				} else if (message.startsWith("conflict:")) { //$NON-NLS-1$
					/*
					 * We can get the following conflict warnings
					 *    cvs server: conflict: folder/file.ext created independently by second party 
					 *    cvs server: conflict: removed file.txt was modified by second party
					 *    cvs server: conflict: file.txt is modified but no longer in the repository
					 * If we get the above line, we have conflicting additions or deletions and we can expect a server error.
					 * We still get "C foler/file.ext" so we don't need to do anything else (except in the remotely deleted case)
					 */
					if (updateMessageListener != null) {
						if (message.endsWith("is modified but no longer in the repository")) { //$NON-NLS-1$
							// The "C foler/file.ext" will come after this so if whould be ignored!
							String filename = message.substring(10, message.length() - 44);
							filename = stripQuotes(filename);
							updateMessageListener.fileDoesNotExist(commandRoot, filename);
						}
					}
					return new CVSStatus(IStatus.WARNING, CVSStatus.CONFLICT, line, commandRoot);
				} else if (message.startsWith("warning:")) { //$NON-NLS-1$
					/*
					 * We can get the following conflict warnings
					 *    cvs server: warning: folder1/file.ext is not (any longer) pertinent
					 * If we get the above line, we have local changes to a remotely deleted file.
					 */
					if (updateMessageListener != null) {
						if (message.endsWith("is not (any longer) pertinent")) { //$NON-NLS-1$
							String filename = message.substring(9, message.length() - 30);
							updateMessageListener.fileDoesNotExist(commandRoot, filename);
						}
					}
					return new CVSStatus(IStatus.WARNING, CVSStatus.CONFLICT, line, commandRoot);
				} else if (message.startsWith("conflicts")) { //$NON-NLS-1$
					// This line is info only. The server doesn't report an error.
					return new CVSStatus(IStatus.INFO, CVSStatus.CONFLICT, line, commandRoot);
				} else if (message.startsWith("nonmergeable file needs merge")) { //$NON-NLS-1$
					mergingBinary = true;
					mergedBinaryFileRevision = null;
					mergedBinaryFilePath = null;
					return OK;
				} else if (wasMergingBinary) {
					Map variables = MERGED_BINARY_FILE_LINE_1.processServerMessage(message);
					if (variables != null) {
						mergedBinaryFileRevision = (String)variables.get(REVISION_VARIABLE_NAME);
						mergedBinaryFilePath = (String)variables.get(LOCAL_FILE_PATH_VARIABLE_NAME);
						mergingBinary = true;
						return OK;
					}
					variables = MERGED_BINARY_FILE_LINE_2.processServerMessage(message);
					if (variables != null) {
						String backupFile = (String)variables.get(BACKUP_FILE_VARIABLE_NAME);
						try {
							if (mergedBinaryFileRevision != null && mergedBinaryFilePath != null) {
								ICVSFile file = commandRoot.getFile(mergedBinaryFilePath);
								IResource resource = file.getIResource();
								if (resource != null) {
									return new CVSStatus(IStatus.ERROR, CVSStatus.UNMEGERED_BINARY_CONFLICT,
										NLS.bind(CVSMessages.UpdateListener_0, (new Object[] { 
										resource.getFullPath().toString(), 
										mergedBinaryFileRevision, 
										resource.getFullPath().removeLastSegments(1).append(backupFile).toString()})), commandRoot);
								}
							}
						} catch (CVSException e1) {
							CVSProviderPlugin.log(e1);
						}
						return OK;
					}
				}
				
				// Fallthrough case for "cvs server" messages
				if (!message.startsWith("cannot open directory") //$NON-NLS-1$
						&& !message.startsWith("nothing known about")) { //$NON-NLS-1$
					return super.errorLine(line, location, commandRoot, monitor);
				} 
			} else {
				String serverAbortedMessage = getServerAbortedMessage(line, location);
				if (serverAbortedMessage != null) {
					// Strip the prefix from the line
					String message = serverAbortedMessage;
					if (message.startsWith("no such tag")) { //$NON-NLS-1$
						// This is reported from CVS when a tag is used on the update there are no files in the directory
						// To get the folders, the update request should be re-issued for HEAD
						return new CVSStatus(IStatus.WARNING, CVSStatus.NO_SUCH_TAG, line, commandRoot);
					} else if (message.startsWith("Numeric join") && message.endsWith("may not contain a date specifier")) { //$NON-NLS-1$ //$NON-NLS-2$
						// This error indicates a join failed because a date tag was used
						return super.errorLine(line, location, commandRoot, monitor);
					} else {
						return super.errorLine(line, location, commandRoot, monitor);
					}
				} else if (line.equals("rcsmerge: warning: conflicts during merge")) { //$NON-NLS-1$
					// There were conflicts in the merge
					return new CVSStatus(IStatus.WARNING, CVSStatus.CONFLICT, line, commandRoot);
				}
			}
		} catch (StringIndexOutOfBoundsException e) {
			// Something went wrong in the parsing of the message.
			// Return a status indicating the problem
			if (Policy.DEBUG) {
				System.out.println("Error parsing E line: " + line); //$NON-NLS-1$
			}
			return new CVSStatus(IStatus.ERROR, CVSStatus.ERROR_LINE_PARSE_FAILURE, line, commandRoot);
		}
		return super.errorLine(line, location, commandRoot, monitor);
	}

	private String stripQuotes(String filename) {
		// CVS version 12 fix - filenames are returned inside quotes
		// Fixes bug 49056
		if (filename.startsWith("`") && filename.endsWith("'")) //$NON-NLS-1$ //$NON-NLS-2$
			filename = filename.substring(1,filename.length()-1);
		return filename;
	}

}
