/*
 * Copyright 2012 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.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
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 com.gitblit.GitBlitException;
import com.gitblit.Keys;
import com.gitblit.models.Menu.ParameterMenuItem;
import com.gitblit.models.NavLink;
import com.gitblit.models.NavLink.DropDownPageMenuNavLink;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebApp;
import com.gitblit.wicket.GitBlitWebSession;
import com.gitblit.wicket.GitblitRedirectException;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.BooleanOption;
import com.gitblit.wicket.panels.ChoiceOption;
import com.gitblit.wicket.panels.ProjectRepositoryPanel;
import com.gitblit.wicket.panels.SshKeysPanel;
import com.gitblit.wicket.panels.TextOption;
import com.gitblit.wicket.panels.UserTitlePanel;

public class UserPage extends RootPage {

	List<ProjectModel> projectModels = new ArrayList<ProjectModel>();

	public UserPage() {
		super();
		throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
	}

	public UserPage(PageParameters params) {
		super(params);
		setup(params);
	}

	@Override
	protected boolean reusePageParameters() {
		return true;
	}

	private void setup(PageParameters params) {
		setupPage("", "");
		// check to see if we should display a login message
		boolean authenticateView = app().settings().getBoolean(Keys.web.authenticateViewPages, true);
		if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
			authenticationError("Please login");
			return;
		}

		String userName = WicketUtils.getUsername(params);
		if (StringUtils.isEmpty(userName)) {
			throw new GitblitRedirectException(GitBlitWebApp.get().getHomePage());
		}

		UserModel user = app().users().getUserModel(userName);
		if (user == null) {
			// construct a temporary user model
			user = new UserModel(userName);
		}


		add(new UserTitlePanel("userTitlePanel", user, user.username));

		UserModel sessionUser = GitBlitWebSession.get().getUser();
		boolean isMyProfile = sessionUser != null && sessionUser.equals(user);

		if (isMyProfile) {
			addPreferences(user);

			if (app().gitblit().isServingSSH()) {
				// show the SSH key management tab
				addSshKeys(user);
			} else {
				// SSH daemon is disabled, hide keys tab
				add(new Label("sshKeysLink").setVisible(false));
				add(new Label("sshKeysTab").setVisible(false));
			}
		} else {
			// visiting user
			add(new Label("preferencesLink").setVisible(false));
			add(new Label("preferencesTab").setVisible(false));

			add(new Label("sshKeysLink").setVisible(false));
			add(new Label("sshKeysTab").setVisible(false));
		}

		List<RepositoryModel> repositories = getRepositories(params);

		Collections.sort(repositories, new Comparator<RepositoryModel>() {
			@Override
			public int compare(RepositoryModel o1, RepositoryModel o2) {
				// reverse-chronological sort
				return o2.lastChange.compareTo(o1.lastChange);
			}
		});

		final ListDataProvider<RepositoryModel> dp = new ListDataProvider<RepositoryModel>(repositories);
		DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repositoryList", dp) {
			private static final long serialVersionUID = 1L;

			@Override
			public void populateItem(final Item<RepositoryModel> item) {
				final RepositoryModel entry = item.getModelObject();

				ProjectRepositoryPanel row = new ProjectRepositoryPanel("repository",
						getLocalizer(), this, showAdmin, entry, getAccessRestrictions());
				item.add(row);
			}
		};
		add(dataView);
	}

	@Override
	protected void addDropDownMenus(List<NavLink> navLinks) {
		PageParameters params = getPageParameters();

		DropDownPageMenuNavLink menu = new DropDownPageMenuNavLink("gb.filters",
				UserPage.class);
		// preserve time filter option on repository choices
		menu.menuItems.addAll(getRepositoryFilterItems(params));

		// preserve repository filter option on time choices
		menu.menuItems.addAll(getTimeFilterItems(params));

		if (menu.menuItems.size() > 0) {
			// Reset Filter
			menu.menuItems.add(new ParameterMenuItem(getString("gb.reset")));
		}

		navLinks.add(menu);
	}

	private void addPreferences(UserModel user) {
		// add preferences
		Form<Void> prefs = new Form<Void>("prefsForm");

		List<Language> languages = Arrays.asList(
				new Language("English","en"),
				new Language("Español", "es"),
				new Language("Français", "fr"),
				new Language("日本語", "ja"),
				new Language("한국말", "ko"),
				new Language("Nederlands", "nl"),
				new Language("Norsk", "no"),
				new Language("Język Polski", "pl"),
				new Language("Português", "pt_BR"),
				new Language("中文", "zh_CN"));

		Locale locale = user.getPreferences().getLocale();
		if (locale == null) {
			// user has not specified language preference
			// try server default preference
			String lc = app().settings().getString(Keys.web.forceDefaultLocale, null);
			if (StringUtils.isEmpty(lc)) {
				// server default language is not configured
				// try browser preference
				Locale sessionLocale = GitBlitWebSession.get().getLocale();
				if (sessionLocale != null) {
					locale = sessionLocale;
				}
			} else {

			}
		}

		Language preferredLanguage = null;
		if (locale != null) {
			String localeCode = locale.getLanguage();
			if (!StringUtils.isEmpty(locale.getCountry())) {
				localeCode += "_" + locale.getCountry();
			}

			for (Language language : languages) {
				if (language.code.equals(localeCode)) {
					// language_COUNTRY match
					preferredLanguage = language;
				} else if (preferredLanguage != null && language.code.startsWith(locale.getLanguage())) {
					// language match
					preferredLanguage = language;
				}
			}
		}

		final IModel<String> displayName = Model.of(user.getDisplayName());
		final IModel<String> emailAddress = Model.of(user.emailAddress == null ? "" : user.emailAddress);
		final IModel<Language> language = Model.of(preferredLanguage);
		final IModel<Boolean> emailMeOnMyTicketChanges = Model.of(user.getPreferences().isEmailMeOnMyTicketChanges());

		prefs.add(new TextOption("displayName",
				getString("gb.displayName"),
				getString("gb.displayNameDescription"),
				displayName).setVisible(app().authentication().supportsDisplayNameChanges(user)));

		prefs.add(new TextOption("emailAddress",
				getString("gb.emailAddress"),
				getString("gb.emailAddressDescription"),
				emailAddress).setVisible(app().authentication().supportsEmailAddressChanges(user)));

		prefs.add(new ChoiceOption<Language>("language",
				getString("gb.languagePreference"),
				getString("gb.languagePreferenceDescription"),
				language,
				languages));

		prefs.add(new BooleanOption("emailMeOnMyTicketChanges",
				getString("gb.emailMeOnMyTicketChanges"),
				getString("gb.emailMeOnMyTicketChangesDescription"),
				emailMeOnMyTicketChanges).setVisible(app().notifier().isSendingMail()));

		prefs.add(new AjaxButton("save") {

			private static final long serialVersionUID = 1L;

			@Override
			protected void onSubmit(AjaxRequestTarget target, Form<?> form) {

				UserModel user = GitBlitWebSession.get().getUser();

				user.displayName = displayName.getObject();
				user.emailAddress = emailAddress.getObject();

				Language lang = language.getObject();
				if (lang != null) {
					user.getPreferences().setLocale(lang.code);
				}

				user.getPreferences().setEmailMeOnMyTicketChanges(emailMeOnMyTicketChanges.getObject());

				try {
					app().gitblit().reviseUser(user.username, user);

					setRedirect(true);
					setResponsePage(UserPage.class, WicketUtils.newUsernameParameter(user.username));
				} catch (GitBlitException e) {
					// logger.error("Failed to update user " + user.username, e);
					// error(getString("gb.failedToUpdateUser"), false);
				}
			}
		});

		// add the preferences tab
		add(new Fragment("preferencesLink", "preferencesLinkFragment", this).setRenderBodyOnly(true));
		Fragment fragment = new Fragment("preferencesTab", "preferencesTabFragment", this);
		fragment.add(prefs);
		add(fragment.setRenderBodyOnly(true));
	}

	private void addSshKeys(final UserModel user) {
		Fragment keysTab = new Fragment("sshKeysTab", "sshKeysTabFragment", this);
		keysTab.add(new SshKeysPanel("sshKeysPanel", user));

		// add the SSH keys tab
		add(new Fragment("sshKeysLink", "sshKeysLinkFragment", this).setRenderBodyOnly(true));
		add(keysTab.setRenderBodyOnly(true));
	}

	private class Language implements Serializable {

		private static final long serialVersionUID = 1L;

		final String name;
		final String code;

		public Language(String name, String code) {
			this.name = name;
			this.code = code;
		}

		@Override
		public String toString() {
			return name + " (" + code +")";
		}
	}
}
