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

import org.eclipse.compare.CompareUI;
import org.eclipse.core.runtime.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.core.TeamException;
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.RDiffSummaryListener;
import org.eclipse.team.internal.ccvs.core.resources.*;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.internal.ccvs.ui.*;
import org.eclipse.team.internal.ccvs.ui.Policy;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;

/**
 * Compare the two versions of given remote folders obtained from the two tags specified.
 */
public class RemoteCompareOperation extends RemoteOperation {
	
	private CompareTreeBuilder builder;
	private CVSTag left, right;
	
	/**
	 * Helper class for builder and comparing the resource trees
	 */
	public static class CompareTreeBuilder implements RDiffSummaryListener.IFileDiffListener {
		private ICVSRepositoryLocation location;
		private RemoteFolderTree leftTree, rightTree;
		private CVSTag left, right;

		public CompareTreeBuilder(ICVSRepositoryLocation location, CVSTag left, CVSTag right) {
			this.left = left;
			this.right = right;
			this.location = location;
			reset();
		}
		
		public RemoteFolderTree getLeftTree() {
			return leftTree;
		}
		public RemoteFolderTree getRightTree() {
			return rightTree;
		}
		
		/**
		 * Reset the builder to prepare for a new build
		 */
		public void reset() {
			leftTree = new RemoteFolderTree(null, location, ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME, left);
			leftTree.setChildren(new ICVSRemoteResource[0]);
			rightTree = new RemoteFolderTree(null, location, ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME, right);
			rightTree.setChildren(new ICVSRemoteResource[0]);
		}
		
		/**
		 * Cache the contents for the files that are about to be compares
		 * @throws CVSException
		 */
		public void cacheContents(IProgressMonitor monitor) throws CVSException {
			String[] overlappingFilePaths = getOverlappingFilePaths();
			if (overlappingFilePaths.length > 0) {
				monitor.beginTask(null, 100);
				fetchFileContents(leftTree, overlappingFilePaths, Policy.subMonitorFor(monitor, 50));
				fetchFileContents(rightTree, overlappingFilePaths, Policy.subMonitorFor(monitor, 50));
				monitor.done();
			}
		}
		
		/**
		 * Open the comparison in a compare editor
		 */
		public void openCompareEditor(final IWorkbenchPage page, final String title, final String toolTip) {
			if (leftTree == null || rightTree == null) return;
			Display.getDefault().asyncExec(() -> CompareUI.openCompareEditorOnPage(new CVSCompareEditorInput(title,
					toolTip, new ResourceEditionNode(leftTree), new ResourceEditionNode(rightTree)), page));
		}
		
		/**
		 * Add the predecessor to the left tree and the remote to the right tree.
		 * @param predecessor
		 * @param remote
		 */
		public void addToTrees(ICVSRemoteFile predecessor, ICVSRemoteFile remote) {
			if (remote != null) {
				try {
					Path filePath = new Path(null, remote.getRepositoryRelativePath());
					addFile(rightTree, right, filePath, remote.getRevision());
					getFolder(leftTree, left, filePath.removeLastSegments(1), Path.EMPTY);
				} catch (TeamException e) {
					CVSUIPlugin.log(e);
				}
			}
			if (predecessor != null) {
				try {
					Path filePath = new Path(null, predecessor.getRepositoryRelativePath());
					addFile(leftTree, left, filePath, predecessor.getRevision());
					getFolder(rightTree, right, filePath.removeLastSegments(1), Path.EMPTY);
				} catch (TeamException e) {
					CVSUIPlugin.log(e);
				}
			}
		}
		
		private void addFile(RemoteFolderTree tree, CVSTag tag, Path filePath, String revision) throws CVSException {
			RemoteFolderTree parent = (RemoteFolderTree)getFolder(tree, tag, filePath.removeLastSegments(1), Path.EMPTY);
			String name = filePath.lastSegment();
			ICVSRemoteFile file = new RemoteFile(parent, 0, name, revision, null, getTag(revision, tag));
			addChild(parent, file);
		}
		
		private CVSTag getTag(String revision, CVSTag tag) {
			if (tag == null) {
				tag = new CVSTag(revision, CVSTag.VERSION);
			}
			return tag;
		}

		/* 
		 * Get the folder at the given path in the given tree, creating any missing folders as needed.
		 */
		private ICVSRemoteFolder getFolder(RemoteFolderTree tree, CVSTag tag, IPath remoteFolderPath, IPath parentPath) throws CVSException {
			if (remoteFolderPath.segmentCount() == 0) return tree;
			String name = remoteFolderPath.segment(0);
			ICVSResource child;
			IPath childPath = parentPath.append(name);
			if (tree.childExists(name)) {
				child = tree.getChild(name);
			}  else {
				child = new RemoteFolderTree(tree, tree.getRepository(), childPath.toString(), tag);
				((RemoteFolderTree)child).setChildren(new ICVSRemoteResource[0]);
				addChild(tree, (ICVSRemoteResource)child);
			}
			return getFolder((RemoteFolderTree)child, tag, remoteFolderPath.removeFirstSegments(1), childPath);
		}

		private void addChild(RemoteFolderTree tree, ICVSRemoteResource resource) {
			ICVSRemoteResource[] children = tree.getChildren();
			ICVSRemoteResource[] newChildren;
			if (children == null) {
				newChildren = new ICVSRemoteResource[] { resource };
			} else {
				newChildren = new ICVSRemoteResource[children.length + 1];
				System.arraycopy(children, 0, newChildren, 0, children.length);
				newChildren[children.length] = resource;
			}
			tree.setChildren(newChildren);
		}
		
		@Override
		public void fileDiff(String remoteFilePath, String leftRevision, String rightRevision) {
			try {
				addFile(rightTree, right, new Path(null, remoteFilePath), rightRevision);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
			try {
				addFile(leftTree, left, new Path(null, remoteFilePath), leftRevision);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
		}

		@Override
		public void newFile(String remoteFilePath, String rightRevision) {
			try {
				addFile(rightTree, right, new Path(null, remoteFilePath), rightRevision);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
		}

		@Override
		public void deletedFile(String remoteFilePath, String leftRevision) {
			// The leftRevision may be null in which case the tag is used
			try {
				addFile(leftTree, left, new Path(null, remoteFilePath), leftRevision);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
		}

		@Override
		public void directory(String remoteFolderPath) {
			try {
				getFolder(leftTree, left, new Path(null, remoteFolderPath), Path.EMPTY);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
			try {
				getFolder(rightTree, right, new Path(null, remoteFolderPath), Path.EMPTY);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
		}
		
		private String[] getOverlappingFilePaths() {
			String[] leftFiles = getFilePaths(leftTree);
			String[] rightFiles = getFilePaths(rightTree);
			Set<String> set = new HashSet<>();
			for (int i = 0; i < rightFiles.length; i++) {
				String rightFile = rightFiles[i];
				for (int j = 0; j < leftFiles.length; j++) {
					String leftFile = leftFiles[j];
					if (leftFile.equals(rightFile)) {
						set.add(leftFile);
					}
				}
			}
			return set.toArray(new String[set.size()]);
		}

		private void fetchFileContents(RemoteFolderTree tree, String[] overlappingFilePaths, IProgressMonitor monitor) throws CVSException {
			FileContentCachingService.fetchFileContents(tree, overlappingFilePaths, monitor);
		}

		private String[] getFilePaths(RemoteFolderTree tree) {
			ICVSRemoteResource[] children = tree.getChildren();
			List<String> result = new ArrayList<>();
			for (int i = 0; i < children.length; i++) {
				ICVSRemoteResource resource = children[i];
				if (resource.isContainer()) {
					result.addAll(Arrays.asList(getFilePaths((RemoteFolderTree)resource)));
				} else {
					result.add(resource.getRepositoryRelativePath());
				}
			}
			return result.toArray(new String[result.size()]);
		}
	}
	
	public static CVSTag getTag(ICVSRemoteResource resource) throws CVSException {
		CVSTag tag = null;
		try {
			if (resource.isContainer()) {
				tag = ((ICVSRemoteFolder)resource).getTag();
			} else {
				ICVSRemoteFile file = (ICVSRemoteFile)resource;
				String revision = file.getRevision();
				if (revision.equals(ResourceSyncInfo.ADDED_REVISION)) {
					ResourceSyncInfo info =file.getSyncInfo();
					if (info != null) tag = info.getTag();
				} else {
					tag = new CVSTag(revision, CVSTag.VERSION);
				}
			}
		} catch (TeamException e) {
			throw CVSException.wrapException(e);
		}
		if (tag == null) tag = CVSTag.DEFAULT;
		return tag;
	}
	
	public static RemoteCompareOperation create(IWorkbenchPart part, ICVSRemoteResource remoteResource, CVSTag tag) throws CVSException {
		CVSTag tag0 = getTag(remoteResource);
		CVSTag tag1 = tag;
		if (tag0.getType() == CVSTag.DATE && tag1.getType() == CVSTag.DATE) {
			if (tag0.asDate().after(tag1.asDate())) {
				tag = tag0;
				remoteResource = remoteResource.forTag(tag1);
			}
		}
		return new RemoteCompareOperation(part, remoteResource, tag);
	}
	
	/**
	 * Compare two versions of the given remote resource.
	 * @param shell
	 * @param remoteResource the resource whose tags are being compared
	 * @param left the earlier tag (not null)
	 * @param right the later tag (not null)
	 */
	protected RemoteCompareOperation(IWorkbenchPart part, ICVSRemoteResource remoteResource, CVSTag tag) {
		super(part, new ICVSRemoteResource[] {remoteResource});
		Assert.isNotNull(tag);
		this.right = tag;
		try {
			this.left = getTag(remoteResource);
		} catch (CVSException e) {
			// This shouldn't happen but log it just in case
			CVSProviderPlugin.log(e);
		}
		if (this.left == null) {
			this.left = CVSTag.DEFAULT;
		}
		builder = new CompareTreeBuilder(remoteResource.getRepository(), left, right);
	}

	/*
	 * This command only supports the use of a single resource
	 */
	private ICVSRemoteResource getRemoteResource() {
		return getRemoteResources()[0];
	}
	
	@Override
	protected void execute(IProgressMonitor monitor) throws CVSException {
		boolean fetchContents = CVSUIPlugin.getPlugin().getPluginPreferences().getBoolean(ICVSUIConstants.PREF_CONSIDER_CONTENTS);
		monitor.beginTask(getTaskName(), 50 + (fetchContents ? 100 : 0));
		try {
			ICVSRemoteResource resource = getRemoteResource();
			IStatus status = buildTrees(resource, Policy.subMonitorFor(monitor, 50));
			if (status.isOK() && fetchContents) {
				builder.cacheContents(Policy.subMonitorFor(monitor, 100));
			}
			collectStatus(status);
			openCompareEditor(builder);
		} finally {
			monitor.done();
		}
	}

	/**
	 * This method is here to allow subclasses to override
	 */
	protected void openCompareEditor(CompareTreeBuilder builder) {
		builder.openCompareEditor(getTargetPage(), null, null);
	}

	/*
	 * Build the two trees uses the reponses from "cvs rdiff -s ...".
	 */
	private IStatus buildTrees(ICVSRemoteResource resource, IProgressMonitor monitor) throws CVSException {
		// Initialize the resulting trees
		builder.reset();
		Command.QuietOption oldOption= CVSProviderPlugin.getPlugin().getQuietness();
		Session session = new Session(resource.getRepository(), builder.getLeftTree(), false);
		try {
			monitor.beginTask(getTaskName(), 100);
			CVSProviderPlugin.getPlugin().setQuietness(Command.VERBOSE);
			session.open(Policy.subMonitorFor(monitor, 10));
			IStatus status = Command.RDIFF.execute(session,
					Command.NO_GLOBAL_OPTIONS,
					getLocalOptions(),
					new ICVSResource[] { resource },
					new RDiffSummaryListener(builder),
					Policy.subMonitorFor(monitor, 90));
			return status;
		} finally {
			try {
				session.close();
			} finally {
				CVSProviderPlugin.getPlugin().setQuietness(oldOption);
			}
			monitor.done();
		}
	}

	private LocalOption[] getLocalOptions() {
		return new LocalOption[] {RDiff.SUMMARY, RDiff.makeTagOption(left), RDiff.makeTagOption(right)};
	}

	@Override
	protected String getTaskName() {
		return NLS.bind(CVSUIMessages.RemoteCompareOperation_0, (new Object[] {left.getName(), right.getName(), getRemoteResource().getRepositoryRelativePath()})); 
	}
	
	protected IWorkbenchPage getTargetPage() {
		return TeamUIPlugin.getActivePage();
	}
}
