/*******************************************************************************
 * 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);
		}
        
		/* (non-Javadoc)
		 * @see org.eclipse.team.internal.ccvs.core.client.listeners.RDiffSummaryListener.IFileDiffListener#fileDiff(java.lang.String, java.lang.String, java.lang.String)
		 */
		@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);
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.team.internal.ccvs.core.client.listeners.RDiffSummaryListener.IFileDiffListener#newFile(java.lang.String, java.lang.String)
		 */
		@Override
		public void newFile(String remoteFilePath, String rightRevision) {
			try {
				addFile(rightTree, right, new Path(null, remoteFilePath), rightRevision);
			} catch (CVSException e) {
				CVSUIPlugin.log(e);
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.team.internal.ccvs.core.client.listeners.RDiffSummaryListener.IFileDiffListener#deletedFile(java.lang.String)
		 */
		@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);
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.team.internal.ccvs.core.client.listeners.RDiffSummaryListener.IFileDiffListener#directory(java.lang.String)
		 */
		@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];
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
	 */
	@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)};
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.internal.ccvs.ui.operations.CVSOperation#getTaskName()
	 */
	@Override
	protected String getTaskName() {
		return NLS.bind(CVSUIMessages.RemoteCompareOperation_0, (new Object[] {left.getName(), right.getName(), getRemoteResource().getRepositoryRelativePath()})); 
	}
	
	protected IWorkbenchPage getTargetPage() {
		return TeamUIPlugin.getActivePage();
	}
}
