/*
 * 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.pages;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.wicket.PageParameters;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.extensions.markup.html.form.palette.Palette;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.util.CollectionModel;
import org.apache.wicket.model.util.ListModel;

import com.gitblit.Constants.RegistrantType;
import com.gitblit.Constants.Role;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
import com.gitblit.models.RegistrantAccessPermission;
import com.gitblit.models.TeamModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.NonTrimmedPasswordTextField;
import com.gitblit.wicket.RequiresAdminRole;
import com.gitblit.wicket.StringChoiceRenderer;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.panels.RegistrantPermissionsPanel;

@RequiresAdminRole
public class EditUserPage extends RootSubPage {

	private final boolean isCreate;

	public EditUserPage() {
		// create constructor
		super();
		isCreate = true;
		setupPage(new UserModel(""));
		setStatelessHint(false);
		setOutputMarkupId(true);
	}

	public EditUserPage(PageParameters params) {
		// edit constructor
		super(params);
		isCreate = false;
		String name = WicketUtils.getUsername(params);
		UserModel model = app().users().getUserModel(name);
		setupPage(model);
		setStatelessHint(false);
		setOutputMarkupId(true);
	}

	@Override
	protected boolean requiresPageMap() {
		return true;
	}

	@Override
	protected Class<? extends BasePage> getRootNavPageClass() {
		return UsersPage.class;
	}

	protected void setupPage(final UserModel userModel) {
		if (isCreate) {
			super.setupPage(getString("gb.newUser"), "");
		} else {
			super.setupPage(getString("gb.edit"), userModel.username);
		}

		final Model<String> confirmPassword = new Model<String>(
				StringUtils.isEmpty(userModel.password) ? "" : userModel.password);
		CompoundPropertyModel<UserModel> model = new CompoundPropertyModel<UserModel>(userModel);

		// build list of projects including all repositories wildcards
		List<String> repos = getAccessRestrictedRepositoryList(true, userModel);

		List<String> userTeams = new ArrayList<String>();
		for (TeamModel team : userModel.teams) {
			userTeams.add(team.name);
		}
		Collections.sort(userTeams);

		final String oldName = userModel.username;
		final List<RegistrantAccessPermission> permissions = app().repositories().getUserAccessPermissions(userModel);

		final Palette<String> teams = new Palette<String>("teams", new ListModel<String>(
				new ArrayList<String>(userTeams)), new CollectionModel<String>(app().users()
				.getAllTeamNames()), new StringChoiceRenderer(), 10, false);
		Form<UserModel> form = new Form<UserModel>("editForm", model) {

			private static final long serialVersionUID = 1L;

			/*
			 * (non-Javadoc)
			 *
			 * @see org.apache.wicket.markup.html.form.Form#onSubmit()
			 */
			@Override
			protected void onSubmit() {
				if (StringUtils.isEmpty(userModel.username)) {
					error(getString("gb.pleaseSetUsername"));
					return;
				}
				// force username to lower-case
				userModel.username = userModel.username.toLowerCase();
				String username = userModel.username;
				if (isCreate) {
					UserModel model = app().users().getUserModel(username);
					if (model != null) {
						error(MessageFormat.format(getString("gb.usernameUnavailable"), username));
						return;
					}
				}
				boolean rename = !StringUtils.isEmpty(oldName)
						&& !oldName.equalsIgnoreCase(username);
				if (app().authentication().supportsCredentialChanges(userModel)) {
					if (!userModel.password.equals(confirmPassword.getObject())) {
						error(getString("gb.passwordsDoNotMatch"));
						return;
					}
					String password = userModel.password;
					if (!password.toUpperCase().startsWith(StringUtils.MD5_TYPE)
							&& !password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
						// This is a plain text password.
						// Check length.
						int minLength = app().settings().getInteger(Keys.realm.minPasswordLength, 5);
						if (minLength < 4) {
							minLength = 4;
						}
						if (password.trim().length() < minLength) {
							error(MessageFormat.format(getString("gb.passwordTooShort"),
									minLength));
							return;
						}

						// change the cookie
						userModel.cookie = StringUtils.getSHA1(userModel.username + password);

						// Optionally store the password MD5 digest.
						String type = app().settings().getString(Keys.realm.passwordStorage, "md5");
						if (type.equalsIgnoreCase("md5")) {
							// store MD5 digest of password
							userModel.password = StringUtils.MD5_TYPE
									+ StringUtils.getMD5(userModel.password);
						} else if (type.equalsIgnoreCase("combined-md5")) {
							// store MD5 digest of username+password
							userModel.password = StringUtils.COMBINED_MD5_TYPE
									+ StringUtils.getMD5(username + userModel.password);
						}
					} else if (rename
							&& password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
						error(getString("gb.combinedMd5Rename"));
						return;
					}
				}

				// update user permissions
				for (RegistrantAccessPermission repositoryPermission : permissions) {
					if (repositoryPermission.mutable) {
						userModel.setRepositoryPermission(repositoryPermission.registrant, repositoryPermission.permission);
					}
				}

				Iterator<String> selectedTeams = teams.getSelectedChoices();
				userModel.teams.clear();
				while (selectedTeams.hasNext()) {
					TeamModel team = app().users().getTeamModel(selectedTeams.next());
					if (team == null) {
						continue;
					}
					userModel.teams.add(team);
				}

				try {
					if (isCreate) {
						app().gitblit().addUser(userModel);
					} else {
						app().gitblit().reviseUser(oldName, userModel);
					}
				} catch (GitBlitException e) {
					error(e.getMessage());
					return;
				}
				setRedirect(false);
				if (isCreate) {
					// create another user
					info(MessageFormat.format(getString("gb.userCreated"),
							userModel.username));
					setResponsePage(EditUserPage.class);
				} else {
					// back to users page
					setResponsePage(UsersPage.class);
				}
			}
		};

		// do not let the browser pre-populate these fields
		form.add(new SimpleAttributeModifier("autocomplete", "off"));

		// not all user providers support manipulating username and password
		boolean editCredentials = app().authentication().supportsCredentialChanges(userModel);

		// not all user providers support manipulating display name
		boolean editDisplayName = app().authentication().supportsDisplayNameChanges(userModel);

		// not all user providers support manipulating email address
		boolean editEmailAddress = app().authentication().supportsEmailAddressChanges(userModel);

		// not all user providers support manipulating team memberships
		boolean editTeams = app().authentication().supportsTeamMembershipChanges(userModel);

		// not all user providers support manipulating the admin role
		boolean changeAdminRole = app().authentication().supportsRoleChanges(userModel, Role.ADMIN);

		// not all user providers support manipulating the create role
		boolean changeCreateRole = app().authentication().supportsRoleChanges(userModel, Role.CREATE);

		// not all user providers support manipulating the fork role
		boolean changeForkRole = app().authentication().supportsRoleChanges(userModel, Role.FORK);

		// field names reflective match UserModel fields
		form.add(new TextField<String>("username").setEnabled(editCredentials));
		NonTrimmedPasswordTextField passwordField = new NonTrimmedPasswordTextField("password");
		passwordField.setResetPassword(false);
		form.add(passwordField.setEnabled(editCredentials));
		NonTrimmedPasswordTextField confirmPasswordField = new NonTrimmedPasswordTextField("confirmPassword",
				confirmPassword);
		confirmPasswordField.setResetPassword(false);
		form.add(confirmPasswordField.setEnabled(editCredentials));
		form.add(new TextField<String>("displayName").setEnabled(editDisplayName));
		form.add(new TextField<String>("emailAddress").setEnabled(editEmailAddress));

		if (userModel.canAdmin() && !userModel.canAdmin) {
			// user inherits Admin permission
			// display a disabled-yet-checked checkbox
			form.add(new CheckBox("canAdmin", Model.of(true)).setEnabled(false));
		} else {
			form.add(new CheckBox("canAdmin").setEnabled(changeAdminRole));
		}

		if (userModel.canFork() && !userModel.canFork) {
			// user inherits Fork permission
			// display a disabled-yet-checked checkbox
			form.add(new CheckBox("canFork", Model.of(true)).setEnabled(false));
		} else {
			final boolean forkingAllowed = app().settings().getBoolean(Keys.web.allowForking, true);
			form.add(new CheckBox("canFork").setEnabled(forkingAllowed && changeForkRole));
		}

		if (userModel.canCreate() && !userModel.canCreate) {
			// user inherits Create permission
			// display a disabled-yet-checked checkbox
			form.add(new CheckBox("canCreate", Model.of(true)).setEnabled(false));
		} else {
			form.add(new CheckBox("canCreate").setEnabled(changeCreateRole));
		}

		form.add(new CheckBox("excludeFromFederation"));
		form.add(new CheckBox("disabled"));

		form.add(new RegistrantPermissionsPanel("repositories",	RegistrantType.REPOSITORY, repos, permissions, getAccessPermissions()));
		form.add(teams.setEnabled(editTeams));

		form.add(new TextField<String>("organizationalUnit").setEnabled(editDisplayName));
		form.add(new TextField<String>("organization").setEnabled(editDisplayName));
		form.add(new TextField<String>("locality").setEnabled(editDisplayName));
		form.add(new TextField<String>("stateProvince").setEnabled(editDisplayName));
		form.add(new TextField<String>("countryCode").setEnabled(editDisplayName));
		form.add(new Button("save"));
		Button cancel = new Button("cancel") {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSubmit() {
				setResponsePage(UsersPage.class);
			}
		};
		cancel.setDefaultFormProcessing(false);
		form.add(cancel);

		add(form);
	}
}
