/*
 * Copyright 2011 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;

import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import javax.servlet.http.HttpServletRequest;

import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.Request;
import org.apache.wicket.behavior.HeaderContributor;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.resource.ContextRelativeResource;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;

import com.gitblit.Constants;
import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.FederationPullStatus;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.models.FederationModel;
import com.gitblit.models.Metric;
import com.gitblit.utils.HttpUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils;

public class WicketUtils {

	public static void setCssClass(Component container, String value) {
		container.add(new SimpleAttributeModifier("class", value));
	}

	public static void setCssStyle(Component container, String value) {
		container.add(new SimpleAttributeModifier("style", value));
	}

	public static void setCssBackground(Component container, String value) {
		String background = MessageFormat.format("background-color:{0};",
				StringUtils.getColor(value));
		container.add(new SimpleAttributeModifier("style", background));
	}

	public static void setHtmlTooltip(Component container, String value) {
		container.add(new SimpleAttributeModifier("title", value));
	}

	public static void setInputPlaceholder(Component container, String value) {
		container.add(new SimpleAttributeModifier("placeholder", value));
	}

	public static void setChangeTypeCssClass(Component container, ChangeType type) {
		switch (type) {
		case ADD:
			setCssClass(container, "addition");
			break;
		case COPY:
		case RENAME:
			setCssClass(container, "rename");
			break;
		case DELETE:
			setCssClass(container, "deletion");
			break;
		case MODIFY:
			setCssClass(container, "modification");
			break;
		}
	}

	public static void setPermissionClass(Component container, AccessPermission permission) {
		if (permission == null) {
			setCssClass(container, "badge");
			return;
		}
		switch (permission) {
		case REWIND:
		case DELETE:
		case CREATE:
			setCssClass(container, "badge badge-success");
			break;
		case PUSH:
			setCssClass(container, "badge badge-info");
			break;
		case CLONE:
			setCssClass(container, "badge badge-inverse");
			break;
		default:
			setCssClass(container, "badge");
			break;
		}
	}

	public static void setAlternatingBackground(Component c, int i) {
		String clazz = i % 2 == 0 ? "light" : "dark";
		setCssClass(c, clazz);
	}

	public static Label createAuthorLabel(String wicketId, String author) {
		Label label = new Label(wicketId, author);
		WicketUtils.setHtmlTooltip(label, author);
		return label;
	}

	public static ContextImage getPullStatusImage(String wicketId, FederationPullStatus status) {
		String filename = null;
		switch (status) {
		case MIRRORED:
		case PULLED:
			filename = "bullet_green.png";
			break;
		case SKIPPED:
			filename = "bullet_yellow.png";
			break;
		case FAILED:
			filename = "bullet_red.png";
			break;
		case EXCLUDED:
			filename = "bullet_white.png";
			break;
		case PENDING:
		case NOCHANGE:
		default:
			filename = "bullet_black.png";
		}
		return WicketUtils.newImage(wicketId, filename, status.name());
	}

	public static ContextImage getFileImage(String wicketId, String filename) {
		filename = filename.toLowerCase();
		if (filename.endsWith(".java")) {
			return newImage(wicketId, "file_java_16x16.png");
		} else if (filename.endsWith(".rb")) {
			return newImage(wicketId, "file_ruby_16x16.png");
		} else if (filename.endsWith(".php")) {
			return newImage(wicketId, "file_php_16x16.png");
		} else if (filename.endsWith(".cs")) {
			return newImage(wicketId, "file_cs_16x16.png");
		} else if (filename.endsWith(".cpp")) {
			return newImage(wicketId, "file_cpp_16x16.png");
		} else if (filename.endsWith(".c")) {
			return newImage(wicketId, "file_c_16x16.png");
		} else if (filename.endsWith(".h")) {
			return newImage(wicketId, "file_h_16x16.png");
		} else if (filename.endsWith(".sln")) {
			return newImage(wicketId, "file_vs_16x16.png");
		} else if (filename.endsWith(".csv") || filename.endsWith(".xls")
				|| filename.endsWith(".xlsx")) {
			return newImage(wicketId, "file_excel_16x16.png");
		} else if (filename.endsWith(".doc") || filename.endsWith(".docx")) {
			return newImage(wicketId, "file_doc_16x16.png");
		} else if (filename.endsWith(".ppt") || filename.endsWith(".pptx")) {
			return newImage(wicketId, "file_ppt_16x16.png");
		} else if (filename.endsWith(".zip")) {
			return newImage(wicketId, "file_zip_16x16.png");
		} else if (filename.endsWith(".pdf")) {
			return newImage(wicketId, "file_acrobat_16x16.png");
		} else if (filename.endsWith(".htm") || filename.endsWith(".html")) {
			return newImage(wicketId, "file_world_16x16.png");
		} else if (filename.endsWith(".xml")) {
			return newImage(wicketId, "file_code_16x16.png");
		} else if (filename.endsWith(".properties")) {
			return newImage(wicketId, "file_settings_16x16.png");
		}

		String ext = StringUtils.getFileExtension(filename).toLowerCase();
		IStoredSettings settings = GitBlitWebApp.get().settings();
		if (MarkupProcessor.getMarkupExtensions(settings).contains(ext)) {
			return newImage(wicketId, "file_world_16x16.png");
		}
		return newImage(wicketId, "file_16x16.png");
	}

	public static ContextImage getRegistrationImage(String wicketId, FederationModel registration,
			Component c) {
		if (registration.isResultData()) {
			return WicketUtils.newImage(wicketId, "information_16x16.png",
					c.getString("gb.federationResults"));
		} else {
			return WicketUtils.newImage(wicketId, "arrow_left.png",
					c.getString("gb.federationRegistration"));
		}
	}

	public static ContextImage newClearPixel(String wicketId) {
		return newImage(wicketId, "pixel.png");
	}

	public static ContextImage newBlankImage(String wicketId) {
		return newImage(wicketId, "blank.png");
	}

	public static ContextImage newImage(String wicketId, String file) {
		return newImage(wicketId, file, null);
	}

	public static ContextImage newImage(String wicketId, String file, String tooltip) {
		ContextImage img = new ContextImage(wicketId, file);
		if (!StringUtils.isEmpty(tooltip)) {
			setHtmlTooltip(img, tooltip);
		}
		return img;
	}

	public static Label newIcon(String wicketId, String css) {
		Label lbl = new Label(wicketId);
		setCssClass(lbl, css);
		return lbl;
	}

	public static Label newBlankIcon(String wicketId) {
		Label lbl = new Label(wicketId);
		setCssClass(lbl, "");
		lbl.setRenderBodyOnly(true);
		return lbl;
	}

	public static ContextRelativeResource getResource(String file) {
		return new ContextRelativeResource(file);
	}

	public static String getGitblitURL(Request request) {
		HttpServletRequest req = ((WebRequest) request).getHttpServletRequest();
		return HttpUtils.getGitblitURL(req);
	}

	public static HeaderContributor syndicationDiscoveryLink(final String feedTitle,
			final String url) {
		return new HeaderContributor(new IHeaderContributor() {
			private static final long serialVersionUID = 1L;

			@Override
			public void renderHead(IHeaderResponse response) {
				String contentType = "application/rss+xml";

				StringBuilder buffer = new StringBuilder();
				buffer.append("<link rel=\"alternate\" ");
				buffer.append("type=\"").append(contentType).append("\" ");
				buffer.append("title=\"").append(feedTitle).append("\" ");
				buffer.append("href=\"").append(url).append("\" />");
				response.renderString(buffer.toString());
			}
		});
	}

	public static PageParameters newTokenParameter(String token) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("t", token);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newRegistrationParameter(String url,
			String name) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("u", url);
		parameterMap.put("n", name);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newUsernameParameter(String username) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("user", username);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newTeamnameParameter(String teamname) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("team", teamname);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newProjectParameter(String projectName) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("p", projectName);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newRepositoryParameter(String repositoryName) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (!StringUtils.isEmpty(repositoryName)) {
			parameterMap.put("r", repositoryName);
		}
		return new PageParameters(parameterMap);
	}

	public static PageParameters newObjectParameter(String objectId) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("h", objectId);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newObjectParameter(String repositoryName,
			String objectId) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (StringUtils.isEmpty(objectId)) {
			return newRepositoryParameter(repositoryName);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", objectId);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newRangeParameter(String repositoryName,
			String startRange, String endRange) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", startRange + ".." + endRange);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newPathParameter(String repositoryName,
			String objectId, String path) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (StringUtils.isEmpty(path)) {
			return newObjectParameter(repositoryName, objectId);
		}
		if (StringUtils.isEmpty(objectId)) {
			parameterMap.put("r", repositoryName);
			parameterMap.put("f", path);
			return new PageParameters(parameterMap);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", objectId);
		parameterMap.put("f", path);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newLogPageParameter(String repositoryName,
			String objectId, int pageNumber) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (pageNumber <= 1) {
			return newObjectParameter(repositoryName, objectId);
		}
		if (StringUtils.isEmpty(objectId)) {
			parameterMap.put("r", repositoryName);
			parameterMap.put("pg", String.valueOf(pageNumber));
			return new PageParameters(parameterMap);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", objectId);
		parameterMap.put("pg", String.valueOf(pageNumber));
		return new PageParameters(parameterMap);
	}

	public static PageParameters newHistoryPageParameter(String repositoryName,
			String objectId, String path, int pageNumber) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (pageNumber <= 1) {
			return newObjectParameter(repositoryName, objectId);
		}
		if (StringUtils.isEmpty(objectId)) {
			parameterMap.put("r", repositoryName);
			parameterMap.put("f", path);
			parameterMap.put("pg", String.valueOf(pageNumber));
			return new PageParameters(parameterMap);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", objectId);
		parameterMap.put("f", path);
		parameterMap.put("pg", String.valueOf(pageNumber));
		return new PageParameters(parameterMap);
	}

	public static PageParameters newBlobDiffParameter(String repositoryName,
			String baseCommitId, String commitId, String path) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (StringUtils.isEmpty(commitId)) {
			parameterMap.put("r", repositoryName);
			parameterMap.put("f", path);
			parameterMap.put("hb", baseCommitId);
			return new PageParameters(parameterMap);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", commitId);
		parameterMap.put("f", path);
		parameterMap.put("hb", baseCommitId);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newSearchParameter(String repositoryName,
			String commitId, String search, Constants.SearchType type) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (StringUtils.isEmpty(commitId)) {
			parameterMap.put("r", repositoryName);
			parameterMap.put("s", search);
			parameterMap.put("st", type.name());
			return new PageParameters(parameterMap);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", commitId);
		parameterMap.put("s", search);
		parameterMap.put("st", type.name());
		return new PageParameters(parameterMap);
	}

	public static PageParameters newSearchParameter(String repositoryName,
			String commitId, String search, Constants.SearchType type,
			int pageNumber) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		if (StringUtils.isEmpty(commitId)) {
			parameterMap.put("r", repositoryName);
			parameterMap.put("s", search);
			parameterMap.put("st", type.name());
			parameterMap.put("pg", String.valueOf(pageNumber));
			return new PageParameters(parameterMap);
		}
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", commitId);
		parameterMap.put("s", search);
		parameterMap.put("st", type.name());
		parameterMap.put("pg", String.valueOf(pageNumber));
		return new PageParameters(parameterMap);
	}

	public static PageParameters newBlameTypeParameter(String repositoryName,
			String commitId, String path, String blameType) {
		Map<String, String> parameterMap = new HashMap<String, String>();
		parameterMap.put("r", repositoryName);
		parameterMap.put("h", commitId);
		parameterMap.put("f", path);
		parameterMap.put("blametype", blameType);
		return new PageParameters(parameterMap);
	}

	public static PageParameters newTicketsParameters(String repositoryName, String... states) {
		PageParameters tParams = newRepositoryParameter(repositoryName);
		if (states != null) {
			for (String state : states) {
				tParams.add("status", state);
			}
		}
		return tParams;
	}

	public static PageParameters newOpenTicketsParameter(String repositoryName) {
		return newTicketsParameters(repositoryName, TicketsUI.openStatii);
	}

	public static String getProjectName(PageParameters params) {
		return params.getString("p", "");
	}

	public static String getRepositoryName(PageParameters params) {
		return params.getString("r", "");
	}

	public static String getObject(PageParameters params) {
		return params.getString("h", null);
	}

	public static String getPath(PageParameters params) {
		return params.getString("f", null);
	}

	public static String getBaseObjectId(PageParameters params) {
		return params.getString("hb", null);
	}

	public static String getSearchString(PageParameters params) {
		return params.getString("s", null);
	}

	public static String getSearchType(PageParameters params) {
		return params.getString("st", null);
	}

	public static int getPage(PageParameters params) {
		// index from 1
		return params.getInt("pg", 1);
	}

	public static String getRegEx(PageParameters params) {
		return params.getString("x", "");
	}

	public static String getSet(PageParameters params) {
		return params.getString("set", "");
	}

	public static String getTeam(PageParameters params) {
		return params.getString("team", "");
	}

	public static int getDaysBack(PageParameters params) {
		return params.getInt("db", 0);
	}

	public static String getUsername(PageParameters params) {
		return params.getString("user", "");
	}

	public static String getTeamname(PageParameters params) {
		return params.getString("team", "");
	}

	public static String getToken(PageParameters params) {
		return params.getString("t", "");
	}

	public static String getUrlParameter(PageParameters params) {
		return params.getString("u", "");
	}

	public static String getNameParameter(PageParameters params) {
		return params.getString("n", "");
	}

	public static Label createDateLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) {
		return createDateLabel(wicketId, date, timeZone, timeUtils, true);
	}

	public static Label createDateLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils, boolean setCss) {
		String format = GitBlitWebApp.get().settings().getString(Keys.web.datestampShortFormat, "MM/dd/yy");
		DateFormat df = new SimpleDateFormat(format);
		if (timeZone == null) {
			timeZone = GitBlitWebApp.get().getTimezone();
		}
		df.setTimeZone(timeZone);
		String dateString;
		if (date.getTime() == 0) {
			dateString = "--";
		} else {
			dateString = df.format(date);
		}
		String title = null;
		if (date.getTime() <= System.currentTimeMillis()) {
			// past
			title = timeUtils.timeAgo(date);
		}
		if (title != null && (System.currentTimeMillis() - date.getTime()) < 10 * 24 * 60 * 60 * 1000L) {
			String tmp = dateString;
			dateString = title;
			title = tmp;
		}
		Label label = new Label(wicketId, dateString);
		if (setCss) {
			WicketUtils.setCssClass(label, timeUtils.timeAgoCss(date));
		}
		if (!StringUtils.isEmpty(title)) {
			WicketUtils.setHtmlTooltip(label, title);
		}
		return label;
	}

	public static Label createTimeLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) {
		String format = GitBlitWebApp.get().settings().getString(Keys.web.timeFormat, "HH:mm");
		DateFormat df = new SimpleDateFormat(format);
		if (timeZone == null) {
			timeZone = GitBlitWebApp.get().getTimezone();
		}
		df.setTimeZone(timeZone);
		String timeString;
		if (date.getTime() == 0) {
			timeString = "--";
		} else {
			timeString = df.format(date);
		}
		String title = timeUtils.timeAgo(date);
		Label label = new Label(wicketId, timeString);
		if (!StringUtils.isEmpty(title)) {
			WicketUtils.setHtmlTooltip(label, title);
		}
		return label;
	}

	public static Label createDatestampLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) {
		String format = GitBlitWebApp.get().settings().getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");
		DateFormat df = new SimpleDateFormat(format);
		if (timeZone == null) {
			timeZone = GitBlitWebApp.get().getTimezone();
		}
		df.setTimeZone(timeZone);
		String dateString;
		if (date.getTime() == 0) {
			dateString = "--";
		} else {
			dateString = df.format(date);
		}
		String title = null;
		if (TimeUtils.isToday(date, timeZone)) {
			title = timeUtils.today();
		} else if (TimeUtils.isYesterday(date, timeZone)) {
			title = timeUtils.yesterday();
		} else if (date.getTime() <= System.currentTimeMillis()) {
			// past
			title = timeUtils.timeAgo(date);
		} else {
			// future
			title = timeUtils.inFuture(date);
		}
		if ((System.currentTimeMillis() - date.getTime()) < 10 * 24 * 60 * 60 * 1000L) {
			String tmp = dateString;
			dateString = title;
			title = tmp;
		}
		Label label = new Label(wicketId, dateString);
		if (!StringUtils.isEmpty(title)) {
			WicketUtils.setHtmlTooltip(label, title);
		}
		return label;
	}

	public static Label createTimestampLabel(String wicketId, Date date, TimeZone timeZone, TimeUtils timeUtils) {
		String format = GitBlitWebApp.get().settings().getString(Keys.web.datetimestampLongFormat,
				"EEEE, MMMM d, yyyy HH:mm Z");
		DateFormat df = new SimpleDateFormat(format);
		if (timeZone == null) {
			timeZone = GitBlitWebApp.get().getTimezone();
		}
		df.setTimeZone(timeZone);
		String dateString;
		if (date.getTime() == 0) {
			dateString = "--";
		} else {
			dateString = df.format(date);
		}
		String title = null;
		if (date.getTime() <= System.currentTimeMillis()) {
			// past
			title = timeUtils.timeAgo(date);
		}
		Label label = new Label(wicketId, dateString);
		if (!StringUtils.isEmpty(title)) {
			WicketUtils.setHtmlTooltip(label, title);
		}
		return label;
	}

	public static double maxValue(Collection<Metric> metrics) {
		double max = Double.MIN_VALUE;
		for (Metric m : metrics) {
			if (m.count > max) {
				max = m.count;
			}
		}
		return max;
	}
}
