/*******************************************************************************
 *  Copyright (c) 2011, 2016 GitHub Inc. and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
 *    Thomas Wolf <thomas.wolf@paranor.ch> - preference-based date formatting
 *******************************************************************************/
package org.eclipse.egit.ui.internal.commit;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.AdapterUtils;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.UIUtils;
import org.eclipse.egit.ui.internal.GitLabelProvider;
import org.eclipse.egit.ui.internal.PreferenceBasedDateFormatter;
import org.eclipse.egit.ui.internal.UIIcons;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.dialogs.SpellcheckableMessageArea;
import org.eclipse.egit.ui.internal.history.CommitFileDiffViewer;
import org.eclipse.egit.ui.internal.history.FileDiff;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.RevWalkUtils;
import org.eclipse.jgit.util.GitDateFormatter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.AbstractHyperlink;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.ShowInContext;

/**
 * Commit editor page class displaying author, committer, parent commits,
 * message, and file information in form sections.
 */
public class CommitEditorPage extends FormPage
		implements ISchedulingRule, IShowInSource {

	private static final String SIGNED_OFF_BY = "Signed-off-by: {0} <{1}>"; //$NON-NLS-1$

	/**
	 * Abbreviated length of parent id links displayed
	 */
	public static final int PARENT_LENGTH = 20;

	private LocalResourceManager resources = new LocalResourceManager(
			JFaceResources.getResources());

	private Composite tagLabelArea;

	private Section branchSection;

	private TableViewer branchViewer;

	private Section diffSection;

	private CommitFileDiffViewer diffViewer;

	private FocusTracker focusTracker = new FocusTracker();

	/**
	 * Create commit editor page
	 *
	 * @param editor
	 */
	public CommitEditorPage(FormEditor editor) {
		this(editor, "commitPage", UIText.CommitEditorPage_Title); //$NON-NLS-1$
	}

	/**
	 * Create commit editor page
	 *
	 * @param editor
	 * @param id
	 * @param title
	 */
	public CommitEditorPage(FormEditor editor, String id, String title) {
		super(editor, id, title);
	}

	/**
	 * Add the given {@link Control} to this form's focus tracking.
	 *
	 * @param control
	 *            to add to focus tracking
	 */
	protected void addToFocusTracking(@NonNull Control control) {
		focusTracker.addToFocusTracking(control);
	}

	private void addSectionTextToFocusTracking(@NonNull Section composite) {
		for (Control control : composite.getChildren()) {
			if (control instanceof AbstractHyperlink) {
				addToFocusTracking(control);
			}
		}
	}

	private void hookExpansionGrabbing(final Section section) {
		section.addExpansionListener(new ExpansionAdapter() {

			@Override
			public void expansionStateChanged(ExpansionEvent e) {
				((GridData) section.getLayoutData()).grabExcessVerticalSpace = e
						.getState();
				getManagedForm().getForm().getBody().layout(true, true);
			}
		});
	}

	private Image getImage(ImageDescriptor descriptor) {
		return (Image) this.resources.get(descriptor);
	}

	Section createSection(Composite parent, FormToolkit toolkit, String title,
			int span) {
		Section section = toolkit.createSection(parent,
				ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE
						| ExpandableComposite.EXPANDED);
		GridDataFactory.fillDefaults().span(span, 1).grab(true, true)
				.applyTo(section);
		section.setText(title);
		addSectionTextToFocusTracking(section);
		return section;
	}

	Composite createSectionClient(Section parent, FormToolkit toolkit) {
		Composite client = toolkit.createComposite(parent);
		GridLayoutFactory.fillDefaults().extendedMargins(2, 2, 2, 2)
				.applyTo(client);
		return client;
	}

	private boolean isSignedOffBy(PersonIdent person) {
		RevCommit commit = getCommit().getRevCommit();
		return commit.getFullMessage().indexOf(getSignedOffByLine(person)) != -1;
	}

	private String getSignedOffByLine(PersonIdent person) {
		return MessageFormat.format(SIGNED_OFF_BY, person.getName(),
				person.getEmailAddress());
	}

	private void setPerson(Text text, PersonIdent person, boolean isAuthor) {
		PreferenceBasedDateFormatter formatter = PreferenceBasedDateFormatter
				.create();
		boolean isRelative = formatter
				.getFormat() == GitDateFormatter.Format.RELATIVE;
		String textTemplate = null;
		if (isAuthor) {
			textTemplate = isRelative
					? UIText.CommitEditorPage_LabelAuthorRelative
					: UIText.CommitEditorPage_LabelAuthor;
		} else {
			textTemplate = isRelative
					? UIText.CommitEditorPage_LabelCommitterRelative
					: UIText.CommitEditorPage_LabelCommitter;
		}
		text.setText(MessageFormat.format(textTemplate, person.getName(),
				person.getEmailAddress(), formatter.formatDate(person)));
	}

	private Composite createUserArea(Composite parent, FormToolkit toolkit,
			PersonIdent person, boolean author) {
		Composite userArea = toolkit.createComposite(parent);
		GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(3)
				.applyTo(userArea);

		Label userLabel = toolkit.createLabel(userArea, null);
		userLabel.setImage(getImage(author ? UIIcons.ELCL16_AUTHOR
				: UIIcons.ELCL16_COMMITTER));
		if (author)
			userLabel.setToolTipText(UIText.CommitEditorPage_TooltipAuthor);
		else
			userLabel.setToolTipText(UIText.CommitEditorPage_TooltipCommitter);

		boolean signedOff = isSignedOffBy(person);

		final Text userText = new Text(userArea, SWT.FLAT | SWT.READ_ONLY);
		addToFocusTracking(userText);
		setPerson(userText, person, author);
		toolkit.adapt(userText, false, false);
		userText.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE);
		IPropertyChangeListener uiPrefsListener = (event) -> {
			String property = event.getProperty();
			if (UIPreferences.DATE_FORMAT.equals(property)
					|| UIPreferences.DATE_FORMAT_CHOICE.equals(property)) {
				setPerson(userText, person, author);
				userArea.layout();
			}
		};
		Activator.getDefault().getPreferenceStore().addPropertyChangeListener(uiPrefsListener);
		userText.addDisposeListener((e) -> {
			Activator.getDefault().getPreferenceStore()
					.removePropertyChangeListener(uiPrefsListener);
		});
		GridDataFactory.fillDefaults().span(signedOff ? 1 : 2, 1)
				.applyTo(userText);
		if (signedOff) {
			Label signedOffLabel = toolkit.createLabel(userArea, null);
			signedOffLabel.setImage(getImage(UIIcons.SIGNED_OFF));
			if (author)
				signedOffLabel
						.setToolTipText(UIText.CommitEditorPage_TooltipSignedOffByAuthor);
			else
				signedOffLabel
						.setToolTipText(UIText.CommitEditorPage_TooltipSignedOffByCommitter);
		}

		return userArea;
	}

	void updateSectionClient(Section section, Composite client,
			FormToolkit toolkit) {
		hookExpansionGrabbing(section);
		toolkit.paintBordersFor(client);
		section.setClient(client);
	}

	private void createHeaderArea(Composite parent, FormToolkit toolkit,
			int span) {
		RevCommit commit = getCommit().getRevCommit();
		Composite top = toolkit.createComposite(parent);
		GridDataFactory.fillDefaults().grab(true, false).span(span, 1)
				.applyTo(top);
		GridLayoutFactory.fillDefaults().numColumns(2).applyTo(top);

		Composite userArea = toolkit.createComposite(top);
		GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(1)
				.applyTo(userArea);
		GridDataFactory.fillDefaults().grab(true, false).applyTo(userArea);

		PersonIdent author = commit.getAuthorIdent();
		if (author != null)
			createUserArea(userArea, toolkit, author, true);

		PersonIdent committer = commit.getCommitterIdent();
		if (committer != null && !committer.equals(author))
			createUserArea(userArea, toolkit, committer, false);

		int count = commit.getParentCount();
		if (count > 0)
			createParentsArea(top, toolkit, commit);

		createTagsArea(userArea, toolkit, 2);
	}

	private void createParentsArea(Composite parent, FormToolkit toolkit,
			RevCommit commit) {
		Composite parents = toolkit.createComposite(parent);
		GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(2)
				.applyTo(parents);
		GridDataFactory.fillDefaults().grab(false, false).applyTo(parents);

		for (int i = 0; i < commit.getParentCount(); i++) {
			final RevCommit parentCommit = commit.getParent(i);
			toolkit.createLabel(parents, getParentCommitLabel(i))
					.setForeground(
							toolkit.getColors().getColor(IFormColors.TB_TOGGLE));
			final Hyperlink link = toolkit
					.createHyperlink(parents,
							parentCommit.abbreviate(PARENT_LENGTH).name(),
							SWT.NONE);
			link.addHyperlinkListener(new HyperlinkAdapter() {
				@Override
				public void linkActivated(HyperlinkEvent e) {
					try {
						CommitEditor.open(new RepositoryCommit(getCommit()
								.getRepository(), parentCommit));
						if ((e.getStateMask() & SWT.MOD1) != 0)
							getEditor().close(false);
					} catch (PartInitException e1) {
						Activator.logError(
								"Error opening commit editor", e1);//$NON-NLS-1$
					}
				}
			});
			addToFocusTracking(link);
		}
	}

	@SuppressWarnings("unused")
	String getParentCommitLabel(int i) {
		return UIText.CommitEditorPage_LabelParent;
	}

	private List<Ref> getTags() {
		Repository repository = getCommit().getRepository();
		List<Ref> tags = new ArrayList<>(repository.getTags().values());
		Collections.sort(tags, new Comparator<Ref>() {

			@Override
			public int compare(Ref r1, Ref r2) {
				return Repository.shortenRefName(r1.getName())
						.compareToIgnoreCase(
								Repository.shortenRefName(r2.getName()));
			}
		});
		return tags;
	}

	void createTagsArea(Composite parent, FormToolkit toolkit,
			int span) {
		Composite tagArea = toolkit.createComposite(parent);
		GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false)
				.applyTo(tagArea);
		GridDataFactory.fillDefaults().span(span, 1).grab(true, false)
				.applyTo(tagArea);
		toolkit.createLabel(tagArea, UIText.CommitEditorPage_LabelTags)
				.setForeground(
						toolkit.getColors().getColor(IFormColors.TB_TOGGLE));
		tagLabelArea = toolkit.createComposite(tagArea);
		GridDataFactory.fillDefaults().grab(true, true).applyTo(tagLabelArea);
		GridLayoutFactory.fillDefaults().spacing(1, 1).applyTo(tagLabelArea);
	}

	void fillDiffs(FileDiff[] diffs) {
		diffViewer.setInput(diffs);
		diffSection.setText(getDiffSectionTitle(Integer.valueOf(diffs.length)));
		setSectionExpanded(diffSection, diffs.length != 0);
	}

	static void setSectionExpanded(Section section, boolean expanded) {
		section.setExpanded(expanded);
		((GridData) section.getLayoutData()).grabExcessVerticalSpace = expanded;
	}

	String getDiffSectionTitle(Integer numChanges) {
		return MessageFormat.format(UIText.CommitEditorPage_SectionFiles,
				numChanges);
	}

	void fillTags(FormToolkit toolkit, List<Ref> tags) {
		for (Control child : tagLabelArea.getChildren())
			child.dispose();

		// Hide "Tags" area if no tags to show
		((GridData) tagLabelArea.getParent().getLayoutData()).exclude = tags
				.isEmpty();

		GridLayoutFactory.fillDefaults().spacing(1, 1).numColumns(tags.size())
				.applyTo(tagLabelArea);

		for (Ref tag : tags) {
			ObjectId id = tag.getPeeledObjectId();
			boolean annotated = id != null;
			if (id == null)
				id = tag.getObjectId();
			CLabel tagLabel = new CLabel(tagLabelArea, SWT.NONE);
			toolkit.adapt(tagLabel, false, false);
			if (annotated)
				tagLabel.setImage(getImage(UIIcons.TAG_ANNOTATED));
			else
				tagLabel.setImage(getImage(UIIcons.TAG));
			tagLabel.setText(Repository.shortenRefName(tag.getName()));
		}
	}

	private void createMessageArea(Composite parent, FormToolkit toolkit,
			int span) {
		Section messageSection = createSection(parent, toolkit,
				UIText.CommitEditorPage_SectionMessage, span);
		Composite messageArea = createSectionClient(messageSection, toolkit);

		RevCommit commit = getCommit().getRevCommit();
		String message = commit.getFullMessage();

		SpellcheckableMessageArea textContent = new SpellcheckableMessageArea(
				messageArea, message, true, toolkit.getBorderStyle()) {

			@Override
			protected IAdaptable getDefaultTarget() {
				return new PlatformObject() {
					@Override
					public Object getAdapter(Class adapter) {
						return Platform.getAdapterManager().getAdapter(
								getEditorInput(), adapter);
					}
				};
			}

			@Override
			protected void createMarginPainter() {
				// Disabled intentionally
			}

		};

		if ((toolkit.getBorderStyle() & SWT.BORDER) == 0)
			textContent.setData(FormToolkit.KEY_DRAW_BORDER,
					FormToolkit.TEXT_BORDER);

		StyledText textWidget = textContent.getTextWidget();
		Point size = textWidget.computeSize(SWT.DEFAULT,
				SWT.DEFAULT);
		int yHint = size.y > 80 ? 80 : SWT.DEFAULT;
		GridDataFactory.fillDefaults().hint(SWT.DEFAULT, yHint).minSize(1, 20)
				.grab(true, true).applyTo(textContent);

		addToFocusTracking(textWidget);
		updateSectionClient(messageSection, messageArea, toolkit);
	}

	private void createBranchesArea(Composite parent, FormToolkit toolkit,
			int span) {
		branchSection = createSection(parent, toolkit,
				UIText.CommitEditorPage_SectionBranchesEmpty, span);
		Composite branchesArea = createSectionClient(branchSection, toolkit);

		branchViewer = new TableViewer(toolkit.createTable(branchesArea,
				SWT.V_SCROLL | SWT.H_SCROLL));
		Control control = branchViewer.getControl();
		control.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);
		GridDataFactory.fillDefaults().grab(true, true).hint(SWT.DEFAULT, 50)
				.applyTo(control);
		addToFocusTracking(control);
		branchViewer.setComparator(new ViewerComparator());
		branchViewer.setLabelProvider(new GitLabelProvider() {

			@Override
			public String getText(Object element) {
				return Repository.shortenRefName(super.getText(element));
			}

		});
		branchViewer.setContentProvider(ArrayContentProvider.getInstance());
		updateSectionClient(branchSection, branchesArea, toolkit);
	}

	private void fillBranches(List<Ref> result) {
		branchViewer.setInput(result);
		branchSection.setText(MessageFormat.format(
				UIText.CommitEditorPage_SectionBranches,
				Integer.valueOf(result.size())));
	}

	void createDiffArea(Composite parent, FormToolkit toolkit, int span) {
		diffSection = createSection(parent, toolkit,
				UIText.CommitEditorPage_SectionFilesEmpty, span);
		Composite filesArea = createSectionClient(diffSection, toolkit);

		diffViewer = new CommitFileDiffViewer(filesArea, getSite(), SWT.MULTI
				| SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION
				| toolkit.getBorderStyle());
		Control control = diffViewer.getControl();
		control.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER);
		GridDataFactory.fillDefaults().grab(true, true).applyTo(control);
		addToFocusTracking(control);
		diffViewer.setContentProvider(ArrayContentProvider.getInstance());
		diffViewer.setTreeWalk(getCommit().getRepository(), null);

		updateSectionClient(diffSection, filesArea, toolkit);
	}

	RepositoryCommit getCommit() {
		return AdapterUtils.adapt(getEditor(), RepositoryCommit.class);
	}

	@Override
	protected void createFormContent(IManagedForm managedForm) {
		managedForm.addPart(new FocusManagerFormPart(focusTracker) {

			@Override
			public void setDefaultFocus() {
				getManagedForm().getForm().setFocus();
			}
		});
		Composite body = managedForm.getForm().getBody();
		body.addDisposeListener(new DisposeListener() {

			@Override
			public void widgetDisposed(DisposeEvent e) {
				resources.dispose();
			}
		});
		FillLayout bodyLayout = new FillLayout();
		bodyLayout.marginHeight = 5;
		bodyLayout.marginWidth = 5;
		body.setLayout(bodyLayout);

		FormToolkit toolkit = managedForm.getToolkit();

		Composite displayArea = new Composite(body, toolkit.getOrientation()) {

			@Override
			public boolean setFocus() {
				Control control = focusTracker.getLastFocusControl();
				if (control != null && control.forceFocus()) {
					return true;
				}
				return super.setFocus();
			}
		};
		toolkit.adapt(displayArea);
		GridLayoutFactory.fillDefaults().numColumns(2).applyTo(displayArea);

		createHeaderArea(displayArea, toolkit, 2);
		createMessageArea(displayArea, toolkit, 2);
		createChangesArea(displayArea, toolkit);

		loadSections();
	}

	void createChangesArea(Composite displayArea, FormToolkit toolkit) {
		createDiffArea(displayArea, toolkit, 1);
		createBranchesArea(displayArea, toolkit, 1);
	}

	private List<Ref> loadTags() {
		RepositoryCommit repoCommit = getCommit();
		RevCommit commit = repoCommit.getRevCommit();
		Repository repository = repoCommit.getRepository();
		List<Ref> tags = new ArrayList<>();
		for (Ref tag : getTags()) {
			tag = repository.peel(tag);
			ObjectId id = tag.getPeeledObjectId();
			if (id == null)
				id = tag.getObjectId();
			if (!commit.equals(id))
				continue;
			tags.add(tag);
		}
		return tags;
	}

	private List<Ref> loadBranches() {
		Repository repository = getCommit().getRepository();
		RevCommit commit = getCommit().getRevCommit();
		try (RevWalk revWalk = new RevWalk(repository)) {
			Map<String, Ref> refsMap = new HashMap<>();
			refsMap.putAll(repository.getRefDatabase().getRefs(
					Constants.R_HEADS));
			refsMap.putAll(repository.getRefDatabase().getRefs(
					Constants.R_REMOTES));
			return RevWalkUtils.findBranchesReachableFrom(commit, revWalk, refsMap.values());
		} catch (IOException e) {
			Activator.handleError(e.getMessage(), e, false);
			return Collections.emptyList();
		}
	}

	void loadSections() {
		RepositoryCommit commit = getCommit();
		Job refreshJob = new Job(MessageFormat.format(
				UIText.CommitEditorPage_JobName, commit.getRevCommit().name())) {

			@Override
			protected IStatus run(IProgressMonitor monitor) {
				final List<Ref> tags = loadTags();
				final List<Ref> branches = loadBranches();
				final FileDiff[] diffs = getCommit().getDiffs();

				final ScrolledForm form = getManagedForm().getForm();
				if (UIUtils.isUsable(form))
					form.getDisplay().syncExec(new Runnable() {

						@Override
						public void run() {
							if (!UIUtils.isUsable(form))
								return;

							fillTags(getManagedForm().getToolkit(), tags);
							fillDiffs(diffs);
							fillBranches(branches);
							form.reflow(true);
							form.layout(true, true);
						}
					});

				return Status.OK_STATUS;
			}
		};
		refreshJob.setRule(this);
		refreshJob.schedule();
	}

	/**
	 * Refresh the editor page
	 */
	public void refresh() {
		loadSections();
	}

	@Override
	public void dispose() {
		focusTracker.dispose();
		super.dispose();
	}

	@Override
	public boolean contains(ISchedulingRule rule) {
		return rule == this;
	}

	@Override
	public boolean isConflicting(ISchedulingRule rule) {
		return rule == this;
	}

	@Override
	public ShowInContext getShowInContext() {
		if (diffViewer != null && diffViewer.getControl().isFocusControl()) {
			return diffViewer.getShowInContext();
		}
		return null;
	}
}
