/*******************************************************************************
 * Copyright (c) 2005, 2012 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.ui.operations;

import java.io.*;
import java.util.*;

import org.eclipse.compare.patch.WorkspacePatcherUI;
import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.*;
import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
import org.eclipse.team.internal.ccvs.core.client.listeners.DiffListener;
import org.eclipse.team.internal.ccvs.core.connection.CVSCommunicationException;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.Policy;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.statushandlers.*;

public abstract class DiffOperation extends SingleCommandOperation {

	private static final int UNIFIED_FORMAT = 0;
	private static final int CONTEXT_FORMAT = 1;
	private static final int STANDARD_FORMAT = 2;
	
	protected boolean isMultiPatch;
	protected boolean includeFullPathInformation;
	protected PrintStream stream;
	protected IPath patchRoot;
	protected boolean patchHasContents;
	protected boolean patchHasNewFiles;
	
	/* see bug 116427 */
	private Object destination = null;
	
	/* see bug 159894 */
	private class CustomizableEOLPrintStream extends PrintStream{

		private boolean error = false;
		
		private String defaultLineEnding = "\n";  //$NON-NLS-1$
		
		public CustomizableEOLPrintStream(PrintStream openStream) {
			super(openStream);
			if(CVSProviderPlugin.getPlugin().isUsePlatformLineend()){
				defaultLineEnding = System.getProperty("line.separator"); //$NON-NLS-1$
			}
		}
		
		@Override
		public boolean checkError() {
			return error || super.checkError();
		}

		@Override
		public void println() {
			try{
				write(defaultLineEnding.getBytes());
			} catch (IOException e){
				error = true;
			}
		}
		
		@Override
		public void println(boolean x) {
			print(x);
			println();
		}
		
		@Override
		public void println(char x) {
			print(x);
			println();
		}

		@Override
		public void println(char[] x) {
			print(x);
			println();
		}

		@Override
		public void println(double x) {
			print(x);
			println();
		}

		@Override
		public void println(float x) {
			print(x);
			println();
		}

		@Override
		public void println(int x) {
			print(x);
			println();
		}

		@Override
		public void println(long x) {
			print(x);
			println();
		}

		@Override
		public void println(Object x) {
			print(x);
			println();
		}
		
		@Override
		public void println(String x) {
			print(x);
			println();
		}
	}
	
	public DiffOperation(IWorkbenchPart part, ResourceMapping[] mappings, LocalOption[] options, boolean isMultiPatch, boolean includeFullPathInformation, IPath patchRoot, Object destination) {
		super(part, mappings, options);
		this.isMultiPatch = isMultiPatch;
		this.includeFullPathInformation=includeFullPathInformation;
		this.patchRoot=patchRoot;
		this.patchHasContents=false;
		this.patchHasNewFiles=false;
		this.destination = destination;
	}
	
	@Override
	protected boolean shouldRun(){
		if (super.shouldRun() == false){
			return false;
		}
		Job[] jobs = Job.getJobManager().find(destination);
		if(jobs.length != 0){
			MessageDialog question = new MessageDialog(getShell(), 
					CVSUIMessages.DiffOperation_CreatePatchConflictTitle, null, 
					NLS.bind(CVSUIMessages.DiffOperation_CreatePatchConflictMessage, destination.toString()), 
					MessageDialog.QUESTION, 
					new String[]{IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL}, 
					1);
			if(question.open() == 0){
				Job.getJobManager().cancel(destination);
			} else {
				return false;
			}
		}
		return true;
	}
	
	@Override
	public void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
		try {
			stream = new CustomizableEOLPrintStream(openStream());
			if (isMultiPatch){
				stream.println(WorkspacePatcherUI.getWorkspacePatchHeader());
			}
			super.execute(monitor);
		} finally {
			if (stream != null) {
				stream.close();
			}
		}
	}
 
	/**
	 * Open and return a stream for the diff output.
	 * @return a stream for the diff output
	 */
	protected abstract PrintStream openStream() throws CVSException;
	
	private static Comparator COMPARATOR = new Comparator() {
		private int compare(IResource r1, IResource r2) {
			return r1.getFullPath().toString().compareTo(r2.getFullPath().toString());
		}
		@Override
		public int compare(Object o1, Object o2) {
			IResource r1 = null;
			IResource r2 = null;
			if (o1 instanceof ICVSResource) {
				r1 = ((ICVSResource)o1).getIResource();
			} else {
				r1 = (IResource)o1;
			}
			if (o2 instanceof ICVSResource) {
				r2 = ((ICVSResource)o2).getIResource();
			} else {
				r2 = (IResource)o2;
			}
			return compare(r1, r2);
		}
	};
	@Override
	protected void execute(CVSTeamProvider provider, IResource[] resources, boolean recurse, IProgressMonitor monitor) throws CVSException, InterruptedException {
		
		//add this project to the total projects encountered
		final HashSet<ICVSFile> newFiles = new HashSet<>(); // need HashSet to guard for duplicate entries
		final HashSet<IResource> existingFiles = new HashSet<>(); // need HashSet to guard for duplicate entries
		
		monitor.beginTask(null,100);
		final IProgressMonitor subMonitor = Policy.subMonitorFor(monitor,10);
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
			cvsResource.accept(new ICVSResourceVisitor() {
				@Override
				public void visitFile(ICVSFile file) throws CVSException {
					if (!(file.isIgnored()))  {
						if (!file.isManaged() || file.getSyncInfo().isAdded() ){
							//this is a new file
							if (file.exists())
								newFiles.add(file);
						}else if (file.isModified(subMonitor)){
							existingFiles.add(file.getIResource());
						}
					}
				}
				
				@Override
				public void visitFolder(ICVSFolder folder) throws CVSException {
					// Even if we are not supposed to recurse we still need to go into
					// the root directory.
					if (!folder.exists() || folder.isIgnored() )  {
						return;
					} 
					
					folder.acceptChildren(this);
					
				}
			}, recurse);
		}

		final SortedSet<Object> allFiles = new TreeSet<Object>(COMPARATOR);
		allFiles.addAll(existingFiles);
		allFiles.addAll(newFiles);

		subMonitor.done();
		
		//Check options 
		//Append our diff output to the server diff output.
		// Our diff output includes new files and new files in new directories.
		int format = STANDARD_FORMAT;
	
		LocalOption[] localoptions = getLocalOptions(recurse);
		for (int i = 0; i < localoptions.length; i++)  {
			LocalOption option = localoptions[i];
			if (option.equals(Diff.UNIFIED_FORMAT) ||
				isMultiPatch)  {
				format = UNIFIED_FORMAT;
			} else if (option.equals(Diff.CONTEXT_FORMAT))  {
				format = CONTEXT_FORMAT;
			} 
		}
		
		boolean haveAddedProjectHeader=false;
		
		if (!existingFiles.isEmpty()){
			if (isMultiPatch && !haveAddedProjectHeader){
				haveAddedProjectHeader=true;
				IProject project=resources[0].getProject();
				stream.println(WorkspacePatcherUI.getWorkspacePatchProjectHeader(project));
			}
		}

		if (!newFiles.isEmpty() && Diff.INCLUDE_NEWFILES.isElementOf(localoptions)){
			//Set new file to flag to let us know that we have added something to the current patch
			patchHasNewFiles=true;
			
			if (isMultiPatch &&!haveAddedProjectHeader){
				haveAddedProjectHeader=true;
				IProject project=resources[0].getProject();
				stream.println(WorkspacePatcherUI.getWorkspacePatchProjectHeader(project));
			}
		}
		
		List<Object> existingFilesSubList = new ArrayList<>();
		for (Iterator iter = allFiles.iterator(); iter.hasNext();) {
			Object file = iter.next();
			if (existingFiles.contains(file)) {
				existingFilesSubList.add(file);
			} else if (newFiles.contains(file)){
				addExistingFilesSubListToDiff(provider, existingFilesSubList, recurse, monitor, existingFiles.size());
				ICVSFile cvsFile = (ICVSFile) file;
				addFileToDiff(getNewFileRoot(cvsFile), cvsFile,stream,format);
			}
		}
		addExistingFilesSubListToDiff(provider, existingFilesSubList, recurse, monitor, existingFiles.size());

		monitor.done();
	}

	private void addExistingFilesSubListToDiff(CVSTeamProvider provider, Collection subList, boolean recurse, IProgressMonitor monitor, int existingFilesTotal) throws InterruptedException {
		if (!subList.isEmpty()) {
			int ticks = 90 * subList.size() / existingFilesTotal;
			try{
				super.execute(provider, (IResource[]) subList.toArray(new IResource[subList.size()]), recurse, Policy.subMonitorFor(monitor, ticks));
			} catch(CVSCommunicationException ex){ // see bug 123430
				StatusAdapter adapter = new StatusAdapter(ex.getStatus());
				adapter.setProperty(
						IStatusAdapterConstants.TITLE_PROPERTY,
						CVSUIMessages.DiffOperation_ErrorsOccurredWhileCreatingThePatch);
				StatusManager.getManager().handle(adapter,
						StatusManager.SHOW | StatusManager.NONE);
			} catch (CVSException ex) {
				handleCVSException(ex);
			}
			subList.clear();
		}
	}

	/**
	 * Checks if the exception contain a status that has to be shown to the
	 * user. If yes, the method shows the dialog.
	 * 
	 * @param ex exception to handle
	 */
	private void handleCVSException(CVSException ex) {
		IStatus status = ex.getStatus();
		List<IStatus> toShow = new ArrayList<>();
		IStatus children[] = status.getChildren();
		boolean may = true;
		for (int i = 0; i < children.length; i++) {
			// ignore all errors except those found by DiffListener
			if (children[i].getCode() == CVSStatus.BINARY_FILES_DIFFER
					|| children[i].getCode() == CVSStatus.PROTOCOL_ERROR
					|| children[i].getCode() == CVSStatus.ERROR_LINE) {
				toShow.add(children[i]);
				if (children[i].getCode() == CVSStatus.BINARY_FILES_DIFFER)
					// the patch does not contain some changes for sure
					may = false;
			}
		}
		if (toShow.size() > 0) {
			String msg = may ? CVSUIMessages.DiffOperation_ThePatchMayNotContainAllTheChanges
					: CVSUIMessages.DiffOperation_ThePatchDoesNotContainAllTheChanges;
			StatusAdapter adapter = new StatusAdapter(
					new MultiStatus(
							CVSProviderPlugin.ID,
							CVSStatus.SERVER_ERROR,
							toShow.toArray(new IStatus[toShow.size()]),
							CVSUIMessages.DiffOperation_ErrorsOccurredWhileCreatingThePatch,
							null));
			adapter.setProperty(IStatusAdapterConstants.TITLE_PROPERTY, msg);
			StatusManager.getManager().handle(adapter,
					StatusManager.SHOW | StatusManager.LOG);
		}
	}

	private ICVSFolder getNewFileRoot(ICVSFile cvsFile) {
		ICVSFolder patchRootFolder = getPatchRootFolder();
		if (patchRootFolder != null)
			return patchRootFolder;
		return CVSWorkspaceRoot.getCVSFolderFor(cvsFile.getIResource().getProject());
	}
	
	@Override
	protected IStatus executeCommand(Session session, CVSTeamProvider provider, ICVSResource[] resources, boolean recurse, IProgressMonitor monitor) throws CVSException, InterruptedException {
		
		DiffListener diffListener = new DiffListener(stream);
		
		IStatus status = Command.DIFF.execute(session,
							Command.NO_GLOBAL_OPTIONS,
							getLocalOptions(recurse),
							resources,
							diffListener,
							monitor);
		
		//Once any run of the Diff commands reports that it has written something to the stream, the patch 
		//in its entirety is considered non-empty - until then keep trying to set the flag.
		if (!patchHasContents)
			patchHasContents = diffListener.wroteToStream();

		return status;
	}

	@Override
	protected String getTaskName(CVSTeamProvider provider) {
		return NLS.bind(CVSUIMessages.DiffOperation_0, new String[]{provider.getProject().getName()});
	}

	@Override
	protected String getTaskName() {
		return CVSUIMessages.DiffOperation_1;
	}
	
	@Override
	Map getProviderTraversalMapping(IProgressMonitor monitor) throws CoreException {
		Map providerTraversal = super.getProviderTraversalMapping(monitor);
		SortedMap result = new TreeMap((o1, o2) -> {
			CVSTeamProvider p1 = (CVSTeamProvider) o1;
			CVSTeamProvider p2 = (CVSTeamProvider) o2;
			return COMPARATOR.compare(p1.getProject(), p2.getProject());
		});
		result.putAll(providerTraversal);
		return result;
	}

	private void addFileToDiff(ICVSFolder patchRoot, ICVSFile file, PrintStream printStream, int format) throws CVSException {
		
		String nullFilePrefix = ""; //$NON-NLS-1$
		String newFilePrefix = ""; //$NON-NLS-1$
		String positionInfo = ""; //$NON-NLS-1$
		String linePrefix = ""; //$NON-NLS-1$
		
		String pathString=""; //$NON-NLS-1$

		
		//get the path string for this file
		pathString= file.getRelativePath(patchRoot);
	
		int lines = 0;
		BufferedReader fileReader = new BufferedReader(new InputStreamReader(file.getContents()));
		try {
			while (fileReader.readLine() != null)  {
				lines++;
			}
		} catch (IOException e) {
			throw CVSException.wrapException(file.getIResource(), NLS.bind(CVSUIMessages.DiffOperation_ErrorAddingFileToDiff, new String[] { pathString }), e);
		} finally {
			try {
				fileReader.close();
			} catch (IOException e1) {
				//ignore
			}
		}

		// Ignore empty files
		if (lines == 0)
			return;
		
		switch (format) {
		case UNIFIED_FORMAT:
			nullFilePrefix = "--- ";	//$NON-NLS-1$
			newFilePrefix = "+++ "; 	//$NON-NLS-1$
			positionInfo = "@@ -0,0 +1," + lines + " @@" ;	//$NON-NLS-1$ //$NON-NLS-2$
			linePrefix = "+"; //$NON-NLS-1$
			break;
			
		case CONTEXT_FORMAT :
			nullFilePrefix = "*** ";	//$NON-NLS-1$
			newFilePrefix = "--- ";		//$NON-NLS-1$
			positionInfo = "--- 1," + lines + " ----";	//$NON-NLS-1$ //$NON-NLS-2$
			linePrefix = "+ ";	//$NON-NLS-1$
			break;
			
		default :
			positionInfo = "0a1," + lines;	//$NON-NLS-1$
		linePrefix = "> ";	//$NON-NLS-1$
					break;
		}
		
		fileReader = new BufferedReader(new InputStreamReader(file.getContents()));
		try {
				
			printStream.println("Index: " + pathString);		//$NON-NLS-1$
			printStream.println("===================================================================");	//$NON-NLS-1$
			printStream.println("RCS file: " + pathString);	//$NON-NLS-1$
			printStream.println("diff -N " + pathString);	//$NON-NLS-1$
			
			
			if (format != STANDARD_FORMAT)  {
				printStream.println(nullFilePrefix + "/dev/null	1 Jan 1970 00:00:00 -0000");	//$NON-NLS-1$
				// Technically this date should be the local file date but nobody really cares.
				printStream.println(newFilePrefix + pathString + "	1 Jan 1970 00:00:00 -0000");	//$NON-NLS-1$
			}
			
			if (format == CONTEXT_FORMAT)  {
				printStream.println("***************");	//$NON-NLS-1$
				printStream.println("*** 0 ****");		//$NON-NLS-1$
			}

			printStream.println(positionInfo);

			for (int i = 0; i < lines - 1; i++) {
				printStream.print(linePrefix);
				printStream.println(fileReader.readLine());
			}

			printStream.print(linePrefix);
			readLastLine(fileReader, printStream);
		} catch (IOException e) {
			throw CVSException.wrapException(file.getIResource(), NLS.bind(CVSUIMessages.DiffOperation_ErrorAddingFileToDiff, new String[] { pathString }), e);
		} finally  {
			try {
				fileReader.close();
			} catch (IOException e1) {
			}
		}
	}

	// based on org.eclipse.compare.internal.core.patch.LineReader.readLine()
	private void readLastLine(BufferedReader reader, PrintStream printStream)
			throws IOException {
		boolean sawCRorLF = false;
		boolean sawEOF = false;
		// TODO: hardcoded, set to the same value as initially in LineReader
		boolean ignoreSingleCR = false;
		while (!sawEOF) {
			int c = reader.read();
			if (c == -1) {
				sawEOF = true;
				break;
			}
			printStream.print((char) c);
			if (c == '\n') {
				sawCRorLF = true;
				break;
			}
			if (c == '\r') {
				sawCRorLF = true;
				c = reader.read();
				if (c == -1) {
					sawEOF = true;
					break; // EOF
				}
				if (c != '\n') {
					if (ignoreSingleCR) {
						sawCRorLF = false;
						printStream.print((char) c);
						continue;
					}
				} else { // '\n'
					printStream.print((char) c);
				}
				break;
			}
		}
		if (!sawCRorLF) {
			printStream.println();
			printStream.println("\\ No newline at end of file"); //$NON-NLS-1$
		}
	}

	public void setStream(PrintStream stream) {
		this.stream = new CustomizableEOLPrintStream(stream);
	}

	protected void reportEmptyDiff() {
		StatusAdapter adapter = new StatusAdapter(new Status(IStatus.INFO,
				CVSProviderPlugin.ID,
				CVSUIMessages.GenerateCVSDiff_noDiffsFoundMsg));
		adapter.setProperty(IStatusAdapterConstants.TITLE_PROPERTY,
				CVSUIMessages.GenerateCVSDiff_noDiffsFoundTitle);
		StatusManager.getManager().handle(adapter,
				StatusManager.SHOW);
	}

	@Override
	protected ICVSFolder getLocalRoot(CVSTeamProvider provider) throws CVSException {
		ICVSFolder root = getPatchRootFolder();
		if (root != null)
			return root;
		return super.getLocalRoot(provider);
	}

	private ICVSFolder getPatchRootFolder() {
		if (!isMultiPatch &&
			!includeFullPathInformation){
			//Check to see if the selected patchRoot has enough segments to consider it a folder/resource
			//if not just get the project

			IResource patchFolder = null;
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			if (patchRoot.segmentCount() > 1){
				patchFolder = root.getFolder(patchRoot);
			} else {
				patchFolder = root.getProject(patchRoot.toString());
			}
		
			ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(patchFolder);
			if (!cvsResource.isFolder()) {
				cvsResource = cvsResource.getParent();
			}
			return (ICVSFolder) cvsResource;
		}
		return null;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation#consultModelsForMappings()
	 */
	@Override
	public boolean consultModelsForMappings() {
		return false;
	}
	
	@Override
	public boolean belongsTo(Object family){
		if(family != null && family.equals(destination))
			return true;
		return super.belongsTo(family);
	}

}
