/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     Matt McCutchen (hashproduct+eclipse@gmail.com) - Bug 35390 Three-way compare cannot select (mis-selects) )ancestor resource
 *     Aleksandra Wozniak (aleksandra.k.wozniak@gmail.com) - Bug 239959
 *******************************************************************************/
package org.eclipse.compare.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.ZipFileStructureCreator;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.DiffTreeViewer;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.compare.structuremergeviewer.IDiffContainer;
import org.eclipse.compare.structuremergeviewer.IDiffElement;
import org.eclipse.compare.structuremergeviewer.IStructureComparator;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

import com.ibm.icu.text.MessageFormat;


/**
 * A two-way or three-way compare for arbitrary IResources.
 */
class ResourceCompareInput extends CompareEditorInput {

	private static final boolean NORMALIZE_CASE= true;

	private boolean fThreeWay= false;
	private Object fRoot;
	private IStructureComparator fAncestor;
	private IStructureComparator fLeft;
	private IStructureComparator fRight;
	private IResource fAncestorResource;
	private IResource fLeftResource;
	private IResource fRightResource;
	private DiffTreeViewer fDiffViewer;
	private IAction fOpenAction;

	class MyDiffNode extends DiffNode {

		private boolean fDirty= false;
		private ITypedElement fLastId;
		private String fLastName;


		public MyDiffNode(IDiffContainer parent, int description, ITypedElement ancestor, ITypedElement left, ITypedElement right) {
			super(parent, description, ancestor, left, right);
		}
		@Override
		public void fireChange() {
			super.fireChange();
			setDirty(true);
			fDirty= true;
			if (fDiffViewer != null)
				fDiffViewer.refresh(this);
		}
		void clearDirty() {
			fDirty= false;
		}
		@Override
		public String getName() {
			if (fLastName == null)
				fLastName= super.getName();
			if (fDirty)
				return '<' + fLastName + '>';
			return fLastName;
		}

		@Override
		public ITypedElement getId() {
			ITypedElement id= super.getId();
			if (id == null)
				return fLastId;
			fLastId= id;
			return id;
		}
	}

	static class FilteredBufferedResourceNode extends BufferedResourceNode {
		FilteredBufferedResourceNode(IResource resource) {
			super(resource);
		}
		@Override
		protected IStructureComparator createChild(IResource child) {
			String name= child.getName();
			if (CompareUIPlugin.getDefault().filter(name, child instanceof IContainer, false))
				return null;
			return new FilteredBufferedResourceNode(child);
		}
	}

	/*
	 * Creates an compare editor input for the given selection.
	 */
	ResourceCompareInput(CompareConfiguration config) {
		super(config);
	}

	@Override
	public Viewer createDiffViewer(Composite parent) {
		fDiffViewer= new DiffTreeViewer(parent, getCompareConfiguration()) {
			@Override
			protected void fillContextMenu(IMenuManager manager) {

				if (fOpenAction == null) {
					fOpenAction= new Action() {
						@Override
						public void run() {
							handleOpen(null);
						}
					};
					Utilities.initAction(fOpenAction, getBundle(), "action.CompareContents."); //$NON-NLS-1$
				}

				boolean enable= false;
				ISelection selection= getSelection();
				if (selection instanceof IStructuredSelection) {
					IStructuredSelection ss= (IStructuredSelection)selection;
					if (ss.size() == 1) {
						Object element= ss.getFirstElement();
						if (element instanceof MyDiffNode) {
							ITypedElement te= ((MyDiffNode) element).getId();
							if (te != null)
								enable= !ITypedElement.FOLDER_TYPE.equals(te.getType());
						} else
							enable= true;
					}
				}
				fOpenAction.setEnabled(enable);

				manager.add(fOpenAction);

				super.fillContextMenu(manager);
			}
		};
		return fDiffViewer;
	}

	class SelectAncestorDialog extends MessageDialog {
		private IResource[] theResources;
		IResource ancestorResource;
		IResource leftResource;
		IResource rightResource;

		private Button[] buttons;

		public SelectAncestorDialog(Shell parentShell, IResource[] theResources) {
			super(parentShell, CompareMessages.SelectAncestorDialog_title,
				null, CompareMessages.SelectAncestorDialog_message,
				MessageDialog.QUESTION,
				new String[] { IDialogConstants.OK_LABEL,
					IDialogConstants.CANCEL_LABEL }, 0);
			this.theResources = theResources;
		}

		@Override
		protected Control createCustomArea(Composite parent) {
			Composite composite = new Composite(parent, SWT.NONE);
			composite.setLayout(new GridLayout());
			buttons = new Button[3];
			for (int i = 0; i < 3; i++) {
				buttons[i] = new Button(composite, SWT.RADIO);
				buttons[i].addSelectionListener(selectionListener);
				buttons[i].setText(NLS.bind(CompareMessages.SelectAncestorDialog_option,
					theResources[i].getFullPath().toPortableString()));
				buttons[i].setFont(parent.getFont());
				// set initial state
				buttons[i].setSelection(i == 0);
			}
			pickAncestor(0);
			return composite;
		}

		private void pickAncestor(int i) {
			ancestorResource = theResources[i];
			leftResource = theResources[i == 0 ? 1 : 0];
			rightResource = theResources[i == 2 ? 1 : 2];
		}

		private SelectionListener selectionListener = new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				Button selectedButton = (Button) e.widget;
				if (!selectedButton.getSelection())
					return;
				for (int i = 0; i < 3; i++)
					if (selectedButton == buttons[i])
						pickAncestor(i);
			}
		};
	}
	// If the compare is three-way, this method asks the user which resource
	// to use as the ancestor. Depending on the value of
	// showSelectAncestorDialog flag it uses different dialogs to get the
	// feedback from the user. Returns false if the user cancels the prompt,
	// true otherwise.
	boolean setSelection(ISelection s, Shell shell, boolean showSelectAncestorDialog) {

		if (!showSelectAncestorDialog)
			return showCompareWithOtherResourceDialog(shell, s);

		IResource[] selection= Utilities.getResources(s);

		fThreeWay= selection.length == 3;

		if (fThreeWay) {
			SelectAncestorDialog dialog =
				new SelectAncestorDialog(shell, selection);
			int code = dialog.open();
			if (code != Window.OK)
				return false;

			fAncestorResource= dialog.ancestorResource;
			fAncestor= getStructure(fAncestorResource);
			fLeftResource= dialog.leftResource;
			fRightResource= dialog.rightResource;
		} else {
			fAncestorResource= null;
			fAncestor= null;
			fLeftResource= selection[0];
			fRightResource= selection[1];
		}
		fLeft= getStructure(fLeftResource);
		fRight= getStructure(fRightResource);
		return true;
	}

	private boolean showCompareWithOtherResourceDialog(Shell shell, ISelection s) {
		CompareWithOtherResourceDialog dialog = new CompareWithOtherResourceDialog(shell, s);
		if (dialog.open() != IDialogConstants.OK_ID)
			return false;
		IResource[] selection = dialog.getResult();
		if (!checkSelection(selection))
			return false;

		fThreeWay = selection.length == 3;
		if (fThreeWay) {
			fAncestorResource = selection[0];
			fAncestor = getStructure(fAncestorResource);
			fLeftResource = selection[1];
			fRightResource = selection[2];
		} else {
			fAncestorResource = null;
			fAncestor = null;
			fLeftResource = selection[0];
			fRightResource = selection[1];
		}
		fLeft= getStructure(fLeftResource);
		fRight= getStructure(fRightResource);
		return true;
	}

	private boolean checkSelection(IResource[] resources) {
		for (int i = 0; i < resources.length; i++)
			if (resources[i] == null)
				return false;
		return true;
	}

	/*
	 * Returns true if compare can be executed for the given selection.
	 */
	public boolean isEnabled(ISelection s) {

		IResource[] selection= Utilities.getResources(s);
		if (selection.length < 2 || selection.length > 3)
			return false;

		boolean threeWay= selection.length == 3;

		if (threeWay)
			// It only makes sense if they're all mutually comparable.
			// If not, the user should compare two of them.
			return comparable(selection[0], selection[1])
				&& comparable(selection[0], selection[2])
				&& comparable(selection[1], selection[2]);

		return comparable(selection[0], selection[1]);
	}

	/**
	 * Initializes the images in the compare configuration.
	 */
	void initializeCompareConfiguration() {
		CompareConfiguration cc= getCompareConfiguration();
		if (fLeftResource != null) {
			cc.setLeftLabel(buildLabel(fLeftResource));
			cc.setLeftImage(CompareUIPlugin.getImage(fLeftResource));
		}
		if (fRightResource != null) {
			cc.setRightLabel(buildLabel(fRightResource));
			cc.setRightImage(CompareUIPlugin.getImage(fRightResource));
		}
		if (fThreeWay && fAncestorResource != null) {
			cc.setAncestorLabel(buildLabel(fAncestorResource));
			cc.setAncestorImage(CompareUIPlugin.getImage(fAncestorResource));
		}
	}

	/*
	 * Returns true if both resources are either structured or unstructured.
	 */
	private boolean comparable(IResource c1, IResource c2) {
		return hasStructure(c1) == hasStructure(c2);
	}

	/*
	 * Returns true if the given argument has a structure.
	 */
	private boolean hasStructure(IResource input) {

		if (input instanceof IContainer)
			return true;

		if (input instanceof IFile) {
			IFile file= (IFile) input;
			String type= file.getFileExtension();
			if (type != null) {
				type= normalizeCase(type);
				return "JAR".equals(type) || "ZIP".equals(type);	//$NON-NLS-2$ //$NON-NLS-1$
			}
		}

		return false;
	}

	/*
	 * Creates a <code>IStructureComparator</code> for the given input.
	 * Returns <code>null</code> if no <code>IStructureComparator</code>
	 * can be found for the <code>IResource</code>.
	 */
	private IStructureComparator getStructure(IResource input) {

		if (input instanceof IContainer)
			return new FilteredBufferedResourceNode(input);

		if (input instanceof IFile) {
			IStructureComparator rn= new FilteredBufferedResourceNode(input);
			IFile file= (IFile) input;
			String type= normalizeCase(file.getFileExtension());
			if ("JAR".equals(type) || "ZIP".equals(type)) //$NON-NLS-2$ //$NON-NLS-1$
				return new ZipFileStructureCreator().getStructure(rn);
			return rn;
		}
		return null;
	}

	/*
	 * Performs a two-way or three-way diff on the current selection.
	 */
	@Override
	public Object prepareInput(IProgressMonitor pm) throws InvocationTargetException {

		try {
			// fix for PR 1GFMLFB: ITPUI:WIN2000 - files that are out of sync with the file system appear as empty
			fLeftResource.refreshLocal(IResource.DEPTH_INFINITE, pm);
			fRightResource.refreshLocal(IResource.DEPTH_INFINITE, pm);
			if (fThreeWay && fAncestorResource != null)
				fAncestorResource.refreshLocal(IResource.DEPTH_INFINITE, pm);
			// end fix

			pm.beginTask(Utilities.getString("ResourceCompare.taskName"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$

			String leftLabel= fLeftResource.getName();
			String rightLabel= fRightResource.getName();

			String title;
			if (fThreeWay) {
				String format= Utilities.getString("ResourceCompare.threeWay.title"); //$NON-NLS-1$
				String ancestorLabel= fAncestorResource.getName();
				title= MessageFormat.format(format, ancestorLabel, leftLabel, rightLabel);
			} else {
				String format= Utilities.getString("ResourceCompare.twoWay.title"); //$NON-NLS-1$
				title= MessageFormat.format(format, leftLabel, rightLabel);
			}
			setTitle(title);

			Differencer d= new Differencer() {
				@Override
				protected Object visit(Object parent, int description, Object ancestor, Object left, Object right) {
					return new MyDiffNode((IDiffContainer) parent, description, (ITypedElement)ancestor, (ITypedElement)left, (ITypedElement)right);
				}
			};

			fRoot= d.findDifferences(fThreeWay, pm, null, fAncestor, fLeft, fRight);
			return fRoot;

		} catch (CoreException ex) {
			throw new InvocationTargetException(ex);
		} finally {
			pm.done();
		}
	}

	@Override
	public String getToolTipText() {
		if (fLeftResource != null && fRightResource != null) {
			String leftLabel= fLeftResource.getFullPath().makeRelative().toString();
			String rightLabel= fRightResource.getFullPath().makeRelative().toString();
			if (fThreeWay) {
				String format= Utilities.getString("ResourceCompare.threeWay.tooltip"); //$NON-NLS-1$
				String ancestorLabel= fAncestorResource.getFullPath().makeRelative().toString();
				return MessageFormat.format(format, ancestorLabel, leftLabel, rightLabel);
			}
			String format= Utilities.getString("ResourceCompare.twoWay.tooltip"); //$NON-NLS-1$
			return MessageFormat.format(format, leftLabel, rightLabel);
		}
		// fall back
		return super.getToolTipText();
	}

	private String buildLabel(IResource r) {
		// for a linked resource in a hidden project use its local file system location
		if (r.isLinked() && r.getProject().isHidden())
			return r.getLocation().toString();
		String n= r.getFullPath().toString();
		if (n.charAt(0) == IPath.SEPARATOR)
			return n.substring(1);
		return n;
	}

	@Override
	public void saveChanges(IProgressMonitor pm) throws CoreException {
		super.saveChanges(pm);
		if (fRoot instanceof DiffNode) {
			try {
				commit(pm, (DiffNode) fRoot);
			} finally {
				if (fDiffViewer != null)
					fDiffViewer.refresh();
				setDirty(false);
			}
		}
	}

	/*
	 * Recursively walks the diff tree and commits all changes.
	 */
	private static void commit(IProgressMonitor pm, DiffNode node) throws CoreException {

		if (node instanceof MyDiffNode)
			((MyDiffNode)node).clearDirty();

		ITypedElement left= node.getLeft();
		if (left instanceof BufferedResourceNode)
			((BufferedResourceNode) left).commit(pm);

		ITypedElement right= node.getRight();
		if (right instanceof BufferedResourceNode)
			((BufferedResourceNode) right).commit(pm);

		IDiffElement[] children= node.getChildren();
		if (children != null) {
			for (int i= 0; i < children.length; i++) {
				IDiffElement element= children[i];
				if (element instanceof DiffNode)
					commit(pm, (DiffNode) element);
			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (IFile.class.equals(adapter)) {
			IProgressMonitor pm= new NullProgressMonitor();
			// flush changes in any dirty viewer
			flushViewers(pm);
			IFile[] files= getAdapter(IFile[].class);
			if (files != null && files.length > 0)
				return (T) files[0];	// can only return one: limitation on IDE.saveAllEditors; see #64617
			return null;
		}
		if (IFile[].class.equals(adapter)) {
			HashSet<IFile> collector= new HashSet<>();
			collectDirtyResources(fRoot, collector);
			return (T) collector.toArray(new IFile[collector.size()]);
		}
		return super.getAdapter(adapter);
	}

	private void collectDirtyResources(Object o, Set<IFile> collector) {
		if (o instanceof DiffNode) {
			DiffNode node= (DiffNode) o;

			ITypedElement left= node.getLeft();
			if (left instanceof BufferedResourceNode) {
				BufferedResourceNode bn= (BufferedResourceNode) left;
				if (bn.isDirty()) {
					IResource resource= bn.getResource();
					if (resource instanceof IFile)
						collector.add((IFile) resource);
				}
			}

			ITypedElement right= node.getRight();
			if (right instanceof BufferedResourceNode) {
				BufferedResourceNode bn= (BufferedResourceNode) right;
				if (bn.isDirty()) {
					IResource resource= bn.getResource();
					if (resource instanceof IFile)
						collector.add((IFile) resource);
				}
			}

			IDiffElement[] children= node.getChildren();
			if (children != null) {
				for (int i= 0; i < children.length; i++) {
					IDiffElement element= children[i];
					if (element instanceof DiffNode)
						collectDirtyResources(element, collector);
				}
			}
		}
	}

	private static String normalizeCase(String s) {
		if (NORMALIZE_CASE && s != null)
			return s.toUpperCase();
		return s;
	}

	@Override
	public boolean canRunAsJob() {
		return true;
	}
}

