/*
 * Copyright 2013 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.wicket.pages;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.ListDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.request.target.basic.RedirectRequestTarget;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

import com.gitblit.Keys;
import com.gitblit.models.PathModel.PathChangeModel;
import com.gitblit.models.RefModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.SubmoduleModel;
import com.gitblit.servlet.RawServlet;
import com.gitblit.utils.DiffUtils;
import com.gitblit.utils.DiffUtils.DiffOutput;
import com.gitblit.utils.DiffUtils.DiffOutputType;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.SessionlessForm;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.CommitLegendPanel;
import com.gitblit.wicket.panels.DiffStatPanel;
import com.gitblit.wicket.panels.LinkPanel;
import com.gitblit.wicket.panels.LogPanel;

/**
 * The compare page allows you to compare two branches, tags, or hash ids.
 *
 * @author James Moger
 *
 */
public class ComparePage extends RepositoryPage {

	IModel<String> fromCommitId = new Model<String>("");
	IModel<String> toCommitId = new Model<String>("");

	IModel<String> fromRefId = new Model<String>("");
	IModel<String> toRefId = new Model<String>("");

	public ComparePage(PageParameters params) {
		super(params);
		Repository r = getRepository();
		RepositoryModel repository = getRepositoryModel();

		if (StringUtils.isEmpty(objectId)) {
			// seleciton form
			add(new Label("comparison").setVisible(false));
		} else {
			// active comparison
			Fragment comparison = new Fragment("comparison", "comparisonFragment", this);
			add(comparison);

			RevCommit fromCommit;
			RevCommit toCommit;

			String[] parts = objectId.split("\\.\\.");
			if (parts[0].startsWith("refs/") && parts[1].startsWith("refs/")) {
				// set the ref models
				fromRefId.setObject(parts[0]);
				toRefId.setObject(parts[1]);

				fromCommit = getCommit(r, fromRefId.getObject());
				toCommit = getCommit(r, toRefId.getObject());
			} else {
				// set the id models
				fromCommitId.setObject(parts[0]);
				toCommitId.setObject(parts[1]);

				fromCommit = getCommit(r, fromCommitId.getObject());
				toCommit = getCommit(r, toCommitId.getObject());
			}

			// prepare submodules
			getSubmodules(toCommit);

			final String startId = fromCommit.getId().getName();
			final String endId = toCommit.getId().getName();

			// commit ids
			fromCommitId.setObject(startId);
			toCommitId.setObject(endId);

			final List<String> imageExtensions = app().settings().getStrings(Keys.web.imageExtensions);
			final ImageDiffHandler handler = new ImageDiffHandler(this, repositoryName,
					fromCommit.getName(), toCommit.getName(), imageExtensions);

			final DiffOutput diff = DiffUtils.getDiff(r, fromCommit, toCommit, DiffOutputType.HTML, handler);
			if (handler.getImgDiffCount() > 0) {
				addBottomScript("scripts/imgdiff.js"); // Tiny support script for image diffs
			}

			// add compare diffstat
			int insertions = 0;
			int deletions = 0;
			for (PathChangeModel pcm : diff.stat.paths) {
				insertions += pcm.insertions;
				deletions += pcm.deletions;
			}
			comparison.add(new DiffStatPanel("diffStat", insertions, deletions));

			// compare page links
//			comparison.add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
//					WicketUtils.newRangeParameter(repositoryName, fromCommitId.toString(), toCommitId.getObject())));

			// display list of commits
			comparison.add(new LogPanel("commitList", repositoryName, objectId, r, 0, 0, repository.showRemoteBranches));

			// changed paths list
			comparison.add(new CommitLegendPanel("commitLegend", diff.stat.paths));
			ListDataProvider<PathChangeModel> pathsDp = new ListDataProvider<PathChangeModel>(diff.stat.paths);
			DataView<PathChangeModel> pathsView = new DataView<PathChangeModel>("changedPath", pathsDp) {
				private static final long serialVersionUID = 1L;
				int counter;

				@Override
				public void populateItem(final Item<PathChangeModel> item) {
					final PathChangeModel entry = item.getModelObject();
					Label changeType = new Label("changeType", "");
					WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
					setChangeTypeTooltip(changeType, entry.changeType);
					item.add(changeType);
					item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));

					boolean hasSubmodule = false;
					String submodulePath = null;
					if (entry.isTree()) {
						// tree
						item.add(new LinkPanel("pathName", null, entry.path, TreePage.class,
								WicketUtils
								.newPathParameter(repositoryName, endId, entry.path)));
					} else if (entry.isSubmodule()) {
						// submodule
						String submoduleId = entry.objectId;
						SubmoduleModel submodule = getSubmodule(entry.path);
						submodulePath = submodule.gitblitPath;
						hasSubmodule = submodule.hasSubmodule;

						// add relative link
						item.add(new LinkPanel("pathName", "list", entry.path + " @ " + getShortObjectId(submoduleId), "#n" + entry.objectId));
					} else {
						// add relative link
						item.add(new LinkPanel("pathName", "list", entry.path, "#n" + entry.objectId));
					}

					// quick links
					if (entry.isSubmodule()) {
						// submodule
						item.add(new ExternalLink("patch", "").setEnabled(false));
						item.add(new BookmarkablePageLink<Void>("view", CommitPage.class, WicketUtils
								.newObjectParameter(submodulePath, entry.objectId)).setEnabled(hasSubmodule));
						item.add(new ExternalLink("raw", "").setEnabled(false));
						item.add(new ExternalLink("blame", "").setEnabled(false));
						item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
								.newPathParameter(repositoryName, endId, entry.path))
								.setEnabled(!entry.changeType.equals(ChangeType.ADD)));
					} else {
						// tree or blob
						item.add(new BookmarkablePageLink<Void>("patch", PatchPage.class, WicketUtils
								.newBlobDiffParameter(repositoryName, startId, endId, entry.path))
								.setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
						item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
								.newPathParameter(repositoryName, endId, entry.path))
								.setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
						String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, endId, entry.path);
						item.add(new ExternalLink("raw", rawUrl)
								.setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
						item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils
								.newPathParameter(repositoryName, endId, entry.path))
								.setEnabled(!entry.changeType.equals(ChangeType.ADD)
										&& !entry.changeType.equals(ChangeType.DELETE)));
						item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
								.newPathParameter(repositoryName, endId, entry.path))
								.setEnabled(!entry.changeType.equals(ChangeType.ADD)));
					}
					WicketUtils.setAlternatingBackground(item, counter);
					counter++;
				}
			};
			comparison.add(pathsView);
			comparison.add(new Label("diffText", diff.content).setEscapeModelStrings(false));
		}

		//
		// ref selection form
		//
		SessionlessForm<Void> refsForm = new SessionlessForm<Void>("compareRefsForm", getClass(), getPageParameters()) {

			private static final long serialVersionUID = 1L;

			@Override
			public void onSubmit() {
				String from = ComparePage.this.fromRefId.getObject();
				String to = ComparePage.this.toRefId.getObject();

				PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
				String relativeUrl = urlFor(ComparePage.class, params).toString();
				String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
				getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
			}
		};

		List<String> refs = new ArrayList<String>();
		for (RefModel ref : JGitUtils.getLocalBranches(r, true, -1)) {
			refs.add(ref.getName());
		}
		if (repository.showRemoteBranches) {
			for (RefModel ref : JGitUtils.getRemoteBranches(r, true, -1)) {
				refs.add(ref.getName());
			}
		}
		for (RefModel ref : JGitUtils.getTags(r, true, -1)) {
			refs.add(ref.getName());
		}
		refsForm.add(new DropDownChoice<String>("fromRef", fromRefId, refs).setEnabled(refs.size() > 0));
		refsForm.add(new DropDownChoice<String>("toRef", toRefId, refs).setEnabled(refs.size() > 0));
		add(refsForm);

		//
		// manual ids form
		//
		SessionlessForm<Void> idsForm = new SessionlessForm<Void>("compareIdsForm", getClass(), getPageParameters()) {

			private static final long serialVersionUID = 1L;

			@Override
			public void onSubmit() {
				String from = ComparePage.this.fromCommitId.getObject();
				String to = ComparePage.this.toCommitId.getObject();

				PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
				String relativeUrl = urlFor(ComparePage.class, params).toString();
				String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
				getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
			}
		};

		TextField<String> fromIdField = new TextField<String>("fromId", fromCommitId);
		WicketUtils.setInputPlaceholder(fromIdField, getString("gb.from") + "...");
		idsForm.add(fromIdField);

		TextField<String> toIdField = new TextField<String>("toId", toCommitId);
		WicketUtils.setInputPlaceholder(toIdField, getString("gb.to") + "...");
		idsForm.add(toIdField);
		add(idsForm);

		r.close();
	}

	@Override
	protected String getPageName() {
		return getString("gb.compare");
	}

	@Override
	protected Class<? extends BasePage> getRepoNavPageClass() {
		return ComparePage.class;
	}

	private RevCommit getCommit(Repository r, String rev)
	{
		RevCommit otherCommit = JGitUtils.getCommit(r, rev);
		if (otherCommit == null) {
			error(MessageFormat.format(getString("gb.failedToFindCommit"), rev, repositoryName, getPageName()), true);
		}
		return otherCommit;
	}
}
