/*
 * 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.manager;

import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.UserModel;
import com.gitblit.utils.DeepCopier;
import com.gitblit.utils.ModelUtils;
import com.gitblit.utils.ObjectCache;
import com.gitblit.utils.StringUtils;

/**
 * Project manager handles project-related functions.
 *
 * @author James Moger
 *
 */
public class ProjectManager implements IProjectManager {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	private final Map<String, ProjectModel> projectCache = new ConcurrentHashMap<String, ProjectModel>();

	private final ObjectCache<String> projectMarkdownCache = new ObjectCache<String>();

	private final ObjectCache<String> projectRepositoriesMarkdownCache = new ObjectCache<String>();

	private final IStoredSettings settings;

	private final IRuntimeManager runtimeManager;

	private final IUserManager userManager;

	private final IRepositoryManager repositoryManager;

	private FileBasedConfig projectConfigs;

	public ProjectManager(
			IRuntimeManager runtimeManager,
			IUserManager userManager,
			IRepositoryManager repositoryManager) {

		this.settings = runtimeManager.getSettings();
		this.runtimeManager = runtimeManager;
		this.userManager = userManager;
		this.repositoryManager = repositoryManager;
	}

	@Override
	public ProjectManager start() {
		// load and cache the project metadata
		projectConfigs = new FileBasedConfig(runtimeManager.getFileOrFolder(Keys.web.projectsFile, "${baseFolder}/projects.conf"), FS.detect());
		getProjectConfigs();

		return this;
	}

	@Override
	public ProjectManager stop() {
		return this;
	}

	private void reloadProjectMarkdown(ProjectModel project) {
		// project markdown
		File pmkd = new File(repositoryManager.getRepositoriesFolder(), (project.isRoot ? "" : project.name) + "/project.mkd");
		if (pmkd.exists()) {
			Date lm = new Date(pmkd.lastModified());
			if (!projectMarkdownCache.hasCurrent(project.name, lm)) {
				String mkd = com.gitblit.utils.FileUtils.readContent(pmkd,  "\n");
				projectMarkdownCache.updateObject(project.name, lm, mkd);
			}
			project.projectMarkdown = projectMarkdownCache.getObject(project.name);
		}

		// project repositories markdown
		File rmkd = new File(repositoryManager.getRepositoriesFolder(), (project.isRoot ? "" : project.name) + "/repositories.mkd");
		if (rmkd.exists()) {
			Date lm = new Date(rmkd.lastModified());
			if (!projectRepositoriesMarkdownCache.hasCurrent(project.name, lm)) {
				String mkd = com.gitblit.utils.FileUtils.readContent(rmkd,  "\n");
				projectRepositoriesMarkdownCache.updateObject(project.name, lm, mkd);
			}
			project.repositoriesMarkdown = projectRepositoriesMarkdownCache.getObject(project.name);
		}
	}


	/**
	 * Returns the map of project config.  This map is cached and reloaded if
	 * the underlying projects.conf file changes.
	 *
	 * @return project config map
	 */
	private Map<String, ProjectModel> getProjectConfigs() {
		if (projectCache.isEmpty() || projectConfigs.isOutdated()) {

			try {
				projectConfigs.load();
			} catch (Exception e) {
			}

			// project configs
			String rootName = settings.getString(Keys.web.repositoryRootGroupName, "main");
			ProjectModel rootProject = new ProjectModel(rootName, true);

			Map<String, ProjectModel> configs = new HashMap<String, ProjectModel>();
			// cache the root project under its alias and an empty path
			configs.put("", rootProject);
			configs.put(rootProject.name.toLowerCase(), rootProject);

			for (String name : projectConfigs.getSubsections("project")) {
				ProjectModel project;
				if (name.equalsIgnoreCase(rootName)) {
					project = rootProject;
				} else {
					project = new ProjectModel(name);
				}
				project.title = projectConfigs.getString("project", name, "title");
				project.description = projectConfigs.getString("project", name, "description");

				reloadProjectMarkdown(project);

				configs.put(name.toLowerCase(), project);
			}
			projectCache.clear();
			projectCache.putAll(configs);
		}
		return projectCache;
	}

	/**
	 * Returns a list of project models for the user.
	 *
	 * @param user
	 * @param includeUsers
	 * @return list of projects that are accessible to the user
	 */
	@Override
	public List<ProjectModel> getProjectModels(UserModel user, boolean includeUsers) {
		Map<String, ProjectModel> configs = getProjectConfigs();

		// per-user project lists, this accounts for security and visibility
		Map<String, ProjectModel> map = new TreeMap<String, ProjectModel>();
		// root project
		map.put("", configs.get(""));

		for (RepositoryModel model : repositoryManager.getRepositoryModels(user)) {
			String rootPath = StringUtils.getRootPath(model.name).toLowerCase();
			if (!map.containsKey(rootPath)) {
				ProjectModel project;
				if (configs.containsKey(rootPath)) {
					// clone the project model because it's repository list will
					// be tailored for the requesting user
					project = DeepCopier.copy(configs.get(rootPath));
				} else {
					project = new ProjectModel(rootPath);
				}
				map.put(rootPath, project);
			}
			map.get(rootPath).addRepository(model);
		}

		// sort projects, root project first
		List<ProjectModel> projects;
		if (includeUsers) {
			// all projects
			projects = new ArrayList<ProjectModel>(map.values());
			Collections.sort(projects);
			projects.remove(map.get(""));
			projects.add(0, map.get(""));
		} else {
			// all non-user projects
			projects = new ArrayList<ProjectModel>();
			ProjectModel root = map.remove("");
			for (ProjectModel model : map.values()) {
				if (!model.isUserProject()) {
					projects.add(model);
				}
			}
			Collections.sort(projects);
			projects.add(0, root);
		}
		return projects;
	}

	/**
	 * Returns the project model for the specified user.
	 *
	 * @param name
	 * @param user
	 * @return a project model, or null if it does not exist
	 */
	@Override
	public ProjectModel getProjectModel(String name, UserModel user) {
		for (ProjectModel project : getProjectModels(user, true)) {
			if (project.name.equalsIgnoreCase(name)) {
				return project;
			}
		}
		return null;
	}

	/**
	 * Returns a project model for the Gitblit/system user.
	 *
	 * @param name a project name
	 * @return a project model or null if the project does not exist
	 */
	@Override
	public ProjectModel getProjectModel(String name) {
		Map<String, ProjectModel> configs = getProjectConfigs();
		ProjectModel project = configs.get(name.toLowerCase());
		if (project == null) {
			project = new ProjectModel(name);
			if (ModelUtils.isPersonalRepository(name)) {
				UserModel user = userManager.getUserModel(ModelUtils.getUserNameFromRepoPath(name));
				if (user != null) {
					project.title = user.getDisplayName();
					project.description = "personal repositories";
				}
			}
		} else {
			// clone the object
			project = DeepCopier.copy(project);
		}
		if (StringUtils.isEmpty(name)) {
			// get root repositories
			for (String repository : repositoryManager.getRepositoryList()) {
				if (repository.indexOf('/') == -1) {
					project.addRepository(repository);
				}
			}
		} else {
			// get repositories in subfolder
			String folder = name.toLowerCase() + "/";
			for (String repository : repositoryManager.getRepositoryList()) {
				if (repository.toLowerCase().startsWith(folder)) {
					project.addRepository(repository);
				}
			}
		}
		if (project.repositories.size() == 0) {
			// no repositories == no project
			return null;
		}

		reloadProjectMarkdown(project);
		return project;
	}

	/**
	 * Returns the list of project models that are referenced by the supplied
	 * repository model	list.  This is an alternative method exists to ensure
	 * Gitblit does not call getRepositoryModels(UserModel) twice in a request.
	 *
	 * @param repositoryModels
	 * @param includeUsers
	 * @return a list of project models
	 */
	@Override
	public List<ProjectModel> getProjectModels(List<RepositoryModel> repositoryModels, boolean includeUsers) {
		Map<String, ProjectModel> projects = new LinkedHashMap<String, ProjectModel>();
		for (RepositoryModel repository : repositoryModels) {
			if (!includeUsers && repository.isPersonalRepository()) {
				// exclude personal repositories
				continue;
			}
			if (!projects.containsKey(repository.getProject())) {
				ProjectModel project = getProjectModel(repository.getProject());
				if (project == null) {
					logger.warn(MessageFormat.format("excluding project \"{0}\" from project list because it is empty!",
							repository.getProject()));
					continue;
				}
				projects.put(repository.getProject(), project);
				// clear the repo list in the project because that is the system
				// list, not the user-accessible list and start building the
				// user-accessible list
				project.repositories.clear();
				project.repositories.add(repository.name);
				project.lastChange = repository.lastChange;
			} else {
				// update the user-accessible list
				// this is used for repository count
				ProjectModel project = projects.get(repository.getProject());
				project.repositories.add(repository.name);
				if (project.lastChange.before(repository.lastChange)) {
					project.lastChange = repository.lastChange;
				}
			}
		}
		return new ArrayList<ProjectModel>(projects.values());
	}
}
