/*
 * Copyright 2014 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.panels;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;

import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
import com.gitblit.wicket.GitBlitWebSession;

/**
 * A panel for naming a repository, specifying it's project, and entering a description.
 *
 * @author James Moger
 *
 */
public class RepositoryNamePanel extends BasePanel {

	private static final long serialVersionUID = 1L;

	private String fullName;

	private final IModel<String> projectPath;

	private DropDownChoice<String> pathChoice;

	private final IModel<String> repoName;

	private TextField<String> nameField;

	public RepositoryNamePanel(String wicketId, RepositoryModel repository) {
		super(wicketId);

		GitBlitWebSession session = GitBlitWebSession.get();
		UserModel user = session.getUser();

		// build project set for repository destination
		String defaultPath = null;
		String defaultName = null;
		Set<String> pathNames = new TreeSet<String>();

//		// add all specified project paths
//		if (user.ownerOf != null) {
//			for (String path : user.ownerOf) {
//				if (path.charAt(path.length() - 1) == '/') {
//					projectNames.add(path);
//				}
//			}
//		}
//
		// add the registered/known projects
		for (ProjectModel project : app().projects().getProjectModels(user, false)) {
			// TODO issue-351: user.canAdmin(project)
			if (user.canAdmin()) {
				if (project.isRoot) {
					pathNames.add("/");
				} else {
					pathNames.add(project.name + "/");
				}
			}
		}

		// add the user's personal project namespace
		if (user.canAdmin() || user.canCreate()) {
			pathNames.add(user.getPersonalPath());
		}

		if (!StringUtils.isEmpty(repository.name)) {
			// editing a repository name
			// set the defaultProject to the current repository project
			defaultPath = repository.getProjectPath();
			defaultName = repository.name.substring(defaultPath.length());
			pathNames.add(defaultPath);
		}

		// if default project is not already set, set preference based on the user permissions
		if (defaultPath == null) {
			if (user.canAdmin()) {
				defaultPath = "/";
			} else if (user.canCreate()) {
				defaultPath = user.getPersonalPath();
			}
		}

		projectPath = Model.of(defaultPath);
		pathChoice = new DropDownChoice<String>("projectPath", projectPath, new ArrayList<String>(pathNames));
		repoName = Model.of(defaultName);
		nameField = new TextField<String>("name", repoName);

		// only enable project selection if we actually have multiple choices
		add(pathChoice.setEnabled(pathNames.size() > 1));
		add(nameField);
		add(new TextField<String>("description"));
	}

	public void setEditable(boolean editable) {
		// only enable project selection if we actually have multiple choices
		pathChoice.setEnabled(pathChoice.getChoices().size() > 1 && editable);
		nameField.setEnabled(editable);
	}

	public boolean updateModel(RepositoryModel repositoryModel) {
		// confirm a project path was selected
		if (StringUtils.isEmpty(projectPath.getObject())) {
			error(getString("gb.pleaseSelectProject"));
			return false;
		}

		// confirm a repository name was entered
		if (StringUtils.isEmpty(repoName.getObject())) {
			error(getString("gb.pleaseSetRepositoryName"));
			return false;
		}

		String project = projectPath.getObject();
		String name = repoName.getObject();

		fullName = (project + name).trim();
		fullName = fullName.replace('\\', '/');
		fullName = fullName.replace("//", "/");
		if (fullName.charAt(0) == '/') {
			fullName = fullName.substring(1);
		}
		if (fullName.endsWith("/")) {
			fullName = fullName.substring(0, fullName.length() - 1);
		}

		if (fullName.contains("../")) {
			error(getString("gb.illegalRelativeSlash"));
			return false;
		}
		if (fullName.contains("/../")) {
			error(getString("gb.illegalRelativeSlash"));
			return false;
		}

		// confirm valid characters in repository name
		Character c = StringUtils.findInvalidCharacter(fullName);
		if (c != null) {
			error(MessageFormat.format(getString("gb.illegalCharacterRepositoryName"), c));
			return false;
		}

		repositoryModel.name = fullName;

		return true;
	}

	@Override
	protected boolean getStatelessHint() {
		return false;
	}
}