<?php
/*******************************************************************************
 * Copyright (c) 2010, 2012 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Wayne Beaton (Eclipse Foundation) - initial API and implementation
 *    Wayne Beaton (Eclipse Foundation) - Bug 369905
 *******************************************************************************/

/*
 * This script assumes that it is being included by another script. We
 * assume that the $App variable has already been defined.
 */

require_once(dirname(__FILE__) . "/ProjectRoot.class.php");
require_once(dirname(__FILE__) . "/debug.php");
require_once(dirname(__FILE__) . "/common.php");
trace_file_info(__FILE__);

/**
 * Get a project from the PMI instead of the foundation database.
 *
 * @param string $id a project id of the form 'technology.egit'
 * @return PMIProject
 */
function get_project_from_pmi($id) {
	if (!isValidProjectId($id)) return null;
	if (preg_match('/^polarsys\.(.*)$/',$id, $matches)) {
		$id = $matches[1];
		$url = "https://polarsys.org/json/project/$id";
	} else {
		$url = "http://projects.eclipse.org/json/project/$id";
	}
	if (!$json = file_get_contents($url)) return null;
	
	$all = json_decode($json, true);
	return new PMIProject($all['projects'][$id]);
}

/**
 * PMI stand-in for Project class. The intent is that this
 * is a valid subtype. The current reality is that I'm implementing
 * only those bits of functionality that I'm actually using as I
 * need it.
 * 
 * @see Project
 * @see get_project_from_pmi
 */
class PMIProject {
	var $data;
	
	function __construct($data) {
		$this->data = $data;
	}
	
	function getId() {
		// TODO Get the name (when it's available)
		return $this->data['id'][0]['value'];
	}
	
	/**
	 * @return string
	 */
	function getShortId() {
	    preg_match("/([^\.]+)$/", $this->getId(), $matches);
	    return $matches[1];
	}
	
	function getName() {
		// TODO Get the name (when it's available)
		return $this->data['title'];
	}
	
	function getDescription() {
	    if (!$field = @$this->data['description'][0]) return null;
	    if (!empty($field['summary'])) return $field['summary'];
	    return $field['safe_value'];
	}
	
	function getDevListUrl() {
	    return $this->data['dev_list']['url'];
	}
	
	function getPlanUrl() {
		return $this->data['plan_url'][0]['url'];
	}
	
	function getSourceRepositories() {
		$repositories = array();
		foreach($this->data['source_repo'] as $repo) {
		    if ($local = getSourceRepository($repo['path'], $this))
                $repositories[] = $local; 
		}
		return $repositories;
	}

	function getBugzillaProduct() {
		foreach($this->data['bugzilla'] as $record) {
			if (strlen($record['product']) > 0)
				return $record['product'];
		}
		return null;		
	}
	
	function getBugzillaComponents() {
		$components = array();
		foreach($this->data['bugzilla'] as $record) {
			if (strlen($record['component']) > 0)
				$components[] = $record['component'];
		}
		return $components;
	}
	
	/**
	 * Return the parent of the project. Note that this does
	 * not cache. Subsequent calls will result in an additional
	 * query.
	 */
	function getParent() {
        if (!$id = @$this->data['parent_project'][0]['id']) return;
        return get_project_from_pmi($id);
	}
	
	function getTopLevelProject() {
	    if (!$parent = $this->getParent()) return $this;
	    return $this->getParent()->getTopLevelProject();
	}
}

/**
 * @deprecated use #getProjectRoot()
 */
function get_project_root() {
	return getProjectRoot();
}
/**
 * Lazily create an instance of ProjectRoot; this instance will read in and hold onto
 * the project information. This way, we only read it once.
 * 
 * PRIVATE: THIS IS NOT API
 */
function getProjectRoot() {
	global $_project_root;
	
	if (!$_project_root) $_project_root = new ProjectRoot();
	
	return $_project_root;
}

/**
 * Clear the project cache. Call this method if you need to reload the
 * projects for any reason, or if you just want to try and reclaim some
 * space (though I remain skeptical about PHP's garbage collection).
 */
function clear_project_cache() {
	global $_project_root;
	
	unset($_project_root);
}

/**
 * Force projects to be preloaded. You might use this behaviour
 * to override the default lazy behaviour (which is to load only
 * the active projects) thereby including inactive projects in
 * later queries.
 * 
 * This function is no longer required. Projects load on demand;
 * there is only one way to load.
 * 
 * @deprecated
 * @param bool $activeOnly Load only the active projects (default)
 */
function preloadProjects($activeOnly = true) {
	_loadAllProjects($activeOnly);
}

/**
 * Do the actual load of the projects. Projects are cached.
 * 
 * PRIVATE: THIS IS NOT API
 * 
 * @deprecated This function is unnecessary.
 * @internal
 * @param bool $activeOnly Load only the active projects (default)
 */
function _loadAllProjects($activeOnly = true) {
	global $_project_root;
	$_project_root = new ProjectRoot($activeOnly);
}

/**
 * Answers an array containing all top-level projects. Only
 * active projects are included.
 * 
 * @return Project[]
 */
function getTopLevelProjects() {
	return getProjectRoot()->getTopLevelProjects();
}

/**
 * @deprecated
 * @see #getTopLevelProjects()
 */
function get_project_hierarchy() {
	return getTopLevelProjects();
}

/**
 * This function returns an instance of Project representing the project
 * with the provided $id. Note that this function preserves object
 * identity: if called twice with the same value, it will return the
 * exact same object.
 * 
 * @return Project
 */
function getProject($id) {
	return getProjectRoot()->getProject($id);
}

/**
 * @deprecated use #getProject($id)
 * @return Project
 */
function get_project($id) {
	return getProjectRoot()->get_project($id);
}

/**
 * This function returns all the active projects. 
 * @return Project[]
 */
function getActiveProjects() {
	return getProjectRoot()->getActiveProjects();
}

/**
 * @deprecated use #getActiveProjects()
 * @return Project[]
 */
function get_all_projects() {
	return getActiveProjects();
}

/**
 * This function returns an array containing those projects that have
 * declared participation in the simultaneous release with the provided
 * name.
 * 
 * @param string $name
 */
function getAllProjectsInSimultaneousRelease($name) {
	$all = get_all_projects();
	$projects = array();
	foreach($all as $project) {
		/* @var $project Project */
		if (in_array($name, $project->getSimultaneousReleaseNames())) $projects[] = $project;
	}
	return $projects;
}

/*
 * List of field names in the database.
 * 
 * PRIVATE: THIS FIELD IS NOT API.
 */
$project_fields = array('ProjectId', 'Name','Level','ParentProjectID','Description',
	'UrlDownload','UrlIndex','DateActive','SortOrder','IsActive',
	'BugsName','ProjectPhase','DiskQuotaGB','IsComponent','IsStandard'); 
$project_fields_string = implode(',', $project_fields);

define('PROJECT_LIVELINESS_ACTIVE', 1);
define('PROJECT_LIVELINESS_STALE', 2);
define('PROJECT_LIVELINESS_DEAD', 3);

define('PROJECT_REPO_ALL_GIT', 1);
define('PROJECT_REPO_SOME_GIT', 2);
define('PROJECT_REPO_NO_GIT', 3);
define('PROJECT_REPO_NONE', 4);

class Project {
	/** 
	 * @internal
	 * @var ProjectRoot 
	 */ 
	var $root;
	
	/**
	 * Project information from the 'Foundation' database
	 * @internal
	 */ 
	var $data; 
	
	/** 
	 * Values from the Eclipse database
	 * @internal
	 */ 
	var $values = array(); 
	
	/** 
	 * @internal
	 * @var Project 
	 */ 
	var $parent;
	
	/** 
	 * @internal
	 * @var Project[] 
	 */ 
	var $children = array();
	
	/**
	 * Keep track of the people associated with the project. This
	 * field is lazy-initialized; use the getPeople() method to access.
	 * 
	 * @internal 
	 */ 
	var $people = null;

	/**
	 * An array containing the the projects that the receiver has
	 * been moved from (e.g., if the project moved from a->b->c, then
	 * project c would list (a,b) in this field).
	 * 
	 * @internal
	 * @var Project[]
	 */
	var $movedFrom = array();
	
	/**
	 * @param Project $root
	 * @param mixed $data
	 */
	function __construct($root, $data) {
		$this->root = $root;
		$this->data = $data;
	}
	
	/**
	 * @return string
	 */
	function getId() {
		return $this->data['ProjectId'];
	}
	
	/**
	 * @return Project
	 */
	function getParent() {
		return $this->parent;
	}
	
	function getUrl() {
		return "http://projects.eclipse.org/projects/" . $this->getId();
	}
	
	/**
	 * @return string
	 */
	function getShortId() {
		preg_match("/([^\.]+)$/", $this->getId(), $matches);
		return $matches[1];
	}

	/**
	 * Answer the project's name as it appears in the Project metadata.
	 * If the project metadata has not been specified, get the value
	 * from the Eclipse Foundation Database. If the name has not been 
	 * specified, the ID is answered instead.
	 * 
	 * @return string
	 */
	function getName() {
		if ($name = $this->findFirstValue('projectname')) return $name;
		if ($name = $this->findFirstValue('projectshortname')) return $name;
		return $this->data['Name'] ? $this->data['Name'] : $this->getId();
	}
	
	function getTopLevelProject() {
		if (!$this->parent) return $this;
		return $this->parent->getTopLevelProject();
	}
	
	function getSiblings() {
		return $this->parent ? $this->parent->getChildren() : getTopLevelProjects();
	}
	
	/**
	 * Answer the project's name as it appears in the developer portal
	 * (this value is set by the project's commmitters). If the projectname
	 * field has not been specified, the project's name as it appears
	 * in the Eclipse Foundation Database is answered instead.
	 * 
	 * @return string
	 */
	function getProjectName() {
		$name = $this->findFirstValue('projectname');
		if ($name) return $name;
		return $this->getName();	
	}
	
	/**
	 * Answer the short name of the project as entered in the 
	 * 'projectshortname' field in the portal. If the value is
	 * not set in the portal, the receiver's name is returned instead.
	 * 
	 * @return string
	 */
	function getShortName() {
		$name = $this->findFirstValue('projectshortname');
		return $name ? $name : $this->getName();
	}
	
	/**
	 * Note that this is a fairly expensive operation. We assume that
	 * this function will be called at most once in any session. The current 
	 * implementation does not cache the results, so the caller should
	 * be careful to avoid subsequent calls (or change this implementation).
	 * 
	 * @return string 
	 */
	function getDescription() {	
		$id = $this->getId();
		$raw = $this->getDescriptionUrl();
		$url = normalizeFilePathUrl($raw);
		
		if (!$url) {
			trace("Description URL for $id not provided.");
			return null;
		}
		
		if (preg_match('/\.php$/', $url)) {
			trace("Ignoring PHP description URL for $id.");
			return null;
		}
		
		trace("Description URL for $id is $raw, normalizes to $url.");
		
		$description = @file_get_contents($url);
		if (!$description)  {
			trace("Description for $id not found.");
			return null;
		}
		
		$description = $this->cleanDescription($description);

		if(!trim($description))  {
			trace("Description for $id is empty.");
			return null;
		}
		
		return $description;
	}
	
	/**
	 * The short description is an abridged version of the description. We first
	 * try to obtain the description using the #getParagraph method; if this does
	 * not return a value, we grab the description (assuming that it is available).
	 * Whatever value we start from, we strip out any HTML tags and limit the size
	 * to 100 words. Results vary based on the quality of the input :-(
	 * 
	 * Note that this is a fairly expensive operation. We assume that
	 * this function will be called at most once in any session. The current 
	 * implementation does not cache the results, so the caller should
	 * be careful to avoid subsequent calls (or change this implementation).
	 * 
	 * @return string
	 */
	function getShortDescription() {
		$description = $this->getParagraph();
		if (!$description) $description = $this->getDescription();
		return $this->extractShortDescription($description);
	}
	
	/**
	 * Answer a paragraph describing the receiver, extracted from
	 * the file referenced in the 'paragraphurl' field in the portal,
	 * or <code>null</code> if the field is not specified.
	 * 
	 * @return string|null
	 */
	function getParagraph() {
		$id = $this->getId();
		$raw = $this->getParagraphUrl();
		$url = normalizeFilePathUrl($raw);
		
		if (!$url) {
			trace("Paragraph URL for $id not provided.");
			return null;
		}
		
		trace("Paragraph URL for $id is $raw, normalizes to $url.");
		
		$paragraph = @file_get_contents($url);
		
		if (!$paragraph)  {
			trace("Paragraph for $id not found.");
			return null;
		}
	
		if(!trim($paragraph))  {
			trace("Paragraph for $id is empty.");
			return null;
		}
		
		return $paragraph;
	}
	
	/**
	 * Return the URL for the project. This information is
	 * represented in both the portal and the Foundation database.
	 * The value provided by a project committer in the metadata
	 * (portal) overrides any value that exists in the Foundation 
	 * Database.
	 * 
	 * @string
	 */
	function getProjectUrl() {
		$url = $this->findFirstValue('projecturl');
		if ($url) return $url;
		
		return $this->data['UrlIndex'];
	}
	
	function getPlanUrl() {
		$plan = $this->findFirstValue('projectplanurl');
		if (preg_match('/^http:\/\/(www\.)?eclipse\.org\/projects\/project-plan\.php\?planurl=(.+\.xml)$/', $plan, $matches)) {
			return $matches[2];
		}
		
		return $plan;
	}
	
	function getWikiUrl() {
		return $this->findFirstValue('wikiurl');	
	}
	
	function getIpLogUrl() {
		return $this->findFirstValue('iplogurl');	
	}
	
	function getLogoUrl() {
		return $this->findFirstValue('logourl');	
	}
	
	function getDocumentationUrl() {
		return $this->findFirstValue('documentationurl');
	}

	function getDescriptionUrl() {
		if ($url = $this->findFirstValue('descriptionurl')) return $url;
		
		if ($root = $this->getWebRoot()) return "$root/description.html";
		
		return null;
	}
	
	/**
	 * Answers the root directory for the website of the project.
	 */
	function getWebRoot() {
		$short = end(preg_split('/\./', $this->getId()));
		if (file_exists(normalizeFilePathUrl($short))) return $short;
		return null;
	}

	function getParagraphUrl() {
		return $this->findFirstValue('paragraphurl');
	}
	
	function getDownloadsUrl() {
		return $this->findFirstValue('downloadsurl');
	}
	
	function getGettingStartedUrl() {
		return $this->findFirstValue('gettingstartedurl');
	}
	/**
	 * @return String
	 */
	function getBugzillaProduct() {
		return $this->findFirstValue('bugzilla', 'productname');
	}
	
	/**
	 * Return an array containing the component names for the project.
	 * If no components are specified for this project, then the 
	 * result is an empty array.
	 * 
	 * Components are stored in an single string. Each component is
	 * separated from the next using a comma. We try to be as forgiving
	 * as possible here and trim out leading or trailing spaces.
	 * Since I'm not sure exactly what limitations are placed on
	 * component names, this is probably the best we can do.
	 * 
	 * @return String[]
	 */
	function getBugzillaComponents() {
		$value = $this->findFirstValue('bugzilla', 'components');
		if (!$value) return array();
		$components = array();
		$values = split(',', $value);
		foreach($values as $component) {
			$components[] = trim($component);
		}
		return $components;
	}

	function getBugzillaUrl() {
		return $this->findFirstValue('bugzilla', 'url');
	}
	
	/**
	 * 
	 * @return Review[]
	 */
	function getReviews() {		
		require_once(dirname(__FILE__) . "/Review.class.php");
		return getReviewsForProject($this->getId());
	}
	
	function getProposal() {
		require_once(dirname(__FILE__) . "/Proposal.class.php");
		return getProposalForProject($this->getId());
	}
	
	function getScope() {
		$proposal = $this->getProposal();
		if (!$proposal) return;
		return $proposal->getScope();
	}
	
	/**
	 * Answer the creation review of the receiver or null if
	 * the creation review cannot be found. If $checkParent
	 * (optional) is true (default), then we assume that--if
	 * the receiver does not have its own creation review--it
	 * shares creation with its parent.
	 * 
	 * @return Review|null
	 */
	function getCreationReview($checkParent = true) {
		foreach($this->getReviews() as $review) {
			if ($review->isCreation()) return $review;
		}
		if (!$checkParent) return null;
		if (!$this->parent) return null;		
		return $this->parent->getCreationReview();
	}
	
	/**
	 * Answer the termination review of the receiver or null if
	 * the creation review cannot be found. 
	 * 
	 * @return Review|null
	 */
	function getTerminationReview() {
		foreach($this->getReviews() as $review) {
			if ($review->isTermination()) return $review;
		}
		return null;
	}
	
// At some point, we may consider an approach along these lines.
// For now, it's better to separate methods for each getter to
// better allow for code completion to work.
//	
//	function __call($name, $parameters) {
//		global $projectAPI;
//		
//		$matches = array();
//		if (preg_match('/^get([_\d\w]*)$/')) {
//			$metadata = $projectAPI->findMetaDataForProjectInfo($matches[1]);
//			$value = $this->findFirstValue($metadata['mainkey']);
//			
//		}
//	
//		return parent::__call($name, $description);
//	}
	
	/**
	 * 
	 * @return Newsgroup[]
	 */
	function getNewsgroups() {	
		return $this->getProjectInfoValues('newsgroup');	
	}
	
	function getMailingLists() {
		return $this->getProjectInfoValues('mailinglist');
	}
	
	/**
	 * A project has releases if (a) there is at least one
	 * release documented in the metadata, and (b) there is no
	 * documented release with 'noreleases' as its name.
	 * 
	 * @return bool
	 */
	function hasReleases() {
		return $this->getReleases() ? true : false;
	}
	
	/**
	 * Answers the collection of releases made by the project sorted
	 * in ascending order (i.e. the oldest release is first).
	 * 
	 * @return Release[]
	 */
	function getReleases() {
		$releases = array();
		foreach ($this->getProjectInfoValues('release') as $data) {
			$release = new Release($this, $data);
			if (!$release->isValid()) continue;
			$releases[$release->getName()] = $release;
		}
		
		foreach($this->movedFrom as $project) {
			$trace = trace("Adding releases from " . $project->getId());
			foreach($project->getReleases() as $release) {
				//if (!isset($releases[$release->getName()])) 
					$releases[$release->getName()] = $release;
				//else 
				$trace->trace("Adding " . $release->getName());
			}
		}
		
		usort($releases, array($this, 'sortReleases'));

		return $releases;
	}
	
	/**
	 * This function is used by #renderReleases.
	 * 
	 * @internal
	 * @param Release $release1
	 * @param Release $release2
	 */
	function sortReleases($release1, $release2) {
		$date1 = $release1->getDate();
		$date2 = $release2->getDate();
		if ($date1 == $date2) return 0;
		return $date1 < $date2 ? -1 : 1;
	}
	
	/**
	 * @param $date timestamp
	 * @return Release|null
	 */
	function getReleaseOnDate($date) {
		$string = date('Y-m-d', $date);
		$releases = $this->getReleases();
		foreach ($releases as $release) {
			/* @var $release Release */
			if ($release->getDate() == $string) return $release;
		}
		return null;
	}
	
	/**
	 * @return Release
	 */
	function getGraduationRelease() {
		$releases = array();
		foreach($this->getReleases() as $release) {
			if (preg_match('/(\d+)(\.\d+){1,2}/', $release->getName(), $matches)) {
				$major = $matches[1];
				if ((int)$major > 0) return $release;
			}
		}
		return null;
	}

	/**
	 * @param $name string
	 * @return Release|null
	 */
	function getReleaseNamed($name) {
		$releases = $this->getReleases();
		foreach ($releases as $release) {
			/* @var $release Release */
			if (strcasecmp($release->getName(), $name) == 0) return $release;
		}
		return null;
	}
	
	function hasCommitActivity() {
		foreach($this->getSourceRepositories() as $repository) {
			if ($repository->providesCommitActivity()) return true;
		}
		return false;
	}
	
	/**
	 * This function answers true if the receiver has at least
	 * one source repository specified; it returns false otherwise.
	 * 
	 * @return boolean
	 */
	function hasSourceRepositories() {
		return $this->getSourceRepositories() ? true : false;
	}
	
	function getGitStatus() {
		$types = $this->getSourceRepositoryTypes();
		if (count($types) == 1 && isset($types['git'])) return PROJECT_REPO_ALL_GIT;
		if (isset($types['git']) && count($types) > 1) return PROJECT_REPO_SOME_GIT;
		if (count($types)) return PROJECT_REPO_NO_GIT;
		return PROJECT_REPO_NONE;
	}
	
	/**
	 * This function answers an array of source repository types,
	 * e.g. array('git'=>'git', 'cvs'=>'cvs'). 
	 * 
	 * @return multitype:string
	 */
	function getSourceRepositoryTypes() {
		$types = array();
	
		foreach($this->getSourceRepositories() as $repository) {
			$type = $repository->getType();
			$types[$type] = $type;
		}
	
		return $types;
	}
	
	/**
	 * This function returns a collection of SourceRepository instances,
	 * each representing one of the source repositories associated with
	 * the project. 
	 * 
	 * @return SourceRepository[]
	 */
	function getSourceRepositories() {
		// TODO Cache these results.
		$values = $this->findValues('sourcerepository');
		$repositories = array();
		foreach($values as $repository) {
			if ($sourceRepository = getSourceRepository($repository, $this)) {
				$repositories[$sourceRepository->getName()] = $sourceRepository;
			}
		}
		return $repositories;
	}
	
	function getUniqueSourceRepositories() {
		$repositories = $this->getSourceRepositories();
		$this->removeRedundantRepositories($repositories);
		return $repositories;
	}
	
	/**
	 * @internal
	 * @param SourceRepository[] $repositories
	 */
	function removeRedundantRepositories(&$repositories) {		
		foreach($this->getChildren() as $subproject) {
			foreach($subproject->getUniqueSourceRepositories() as $subrepo) {
				unset($repositories[$subrepo->getName()]);
			}
			$subproject->removeRedundantRepositories($repositories);
		}
	}
	
	function getUpdateSiteUrl() {
		return $this->findFirstValue('updatesiteurl');
	}
	
	function getProjectPhase() {
		return $this->data['ProjectPhase'];
	}
	
	/**
	 * This function answers true if the receiver is marked as
	 * a &quot;Component&quot; in the Eclipse Foundation database.
	 * This is a relatively old concept that predates the 2007 version
	 * of the EDP. Components tend to have their own UNIX groups,
	 * but are considered fully part of the parent project.
	 */
	function isComponent() {
		return $this->data['IsComponent'];
	}
	
	function isActive() {
		return $this->data['IsActive'] == 1;
	}
	
	function isInIncubationPhase() {
		return in_array($this->getProjectPhase(), array('Incubation', 'Incubation.nc'));
	}
	
	function isArchived() {
		return $this->getProjectPhase() == 'Archived';
	}
	
	function isInIncubationConformingPhase() {
		return $this->getProjectPhase() == 'Incubation';
	}

	function isInIncubationNonConformingPhase() {
		return $this->getProjectPhase() == 'Incubation.nc';
	}
	
	function isTopLevel() {
		return !$this->parent;
	}
	
	/**
	 * This function returns an array containing the names of the
	 * simultaneous releases that the receiver participates in.
	 * 
	 * @return string[]
	 */
	function getSimultaneousReleaseNames() {
		$rows = $this->findRows('simultaneousrelease');
		$releases = array();
		foreach ($rows as $row) {
			if ($row['Value'])
				$releases[$row['SubKey']] = true;
		}
		return array_keys($releases);
	}
	
	/**
	 * Returns an instance of SimultaneousReleaseInfo for the receiver,
	 * or <code>null</code> if no information has been provided.
	 * 
	 * @return SimultaneousReleaseInfo
	 */
	function getSimultaneousReleaseInfo($releaseName = null) {
		return getSimultaneousReleaseInfo($this->getId(), $releaseName);
	}
	
	function getLiveliness() {
		$liveliness = PROJECT_LIVELINESS_DEAD;
		foreach($this->getChildren() as $child) {
			$liveliness = min($liveliness, $child->getLiveliness());
		}
		if ($liveliness == PROJECT_LIVELINESS_ACTIVE) return PROJECT_LIVELINESS_ACTIVE;
		if ($this->hasRecentCommitActivity(3)) return PROJECT_LIVELINESS_ACTIVE;
		
		if ($liveliness == PROJECT_LIVELINESS_STALE) return PROJECT_LIVELINESS_STALE;
		if ($this->hasRecentCommitActivity(6)) return PROJECT_LIVELINESS_STALE;
		
		return PROJECT_LIVELINESS_DEAD;
	}
	
	/**
	 * @return int
	 */
	function getActiveCommittersCount() {
		global $App;
	
		$id = $this->getId();
		$result = $App->dashboard_sql("select count(distinct login) as count from ProjectCommitterActivity where project='$id'");
	
		while($row = mysql_fetch_assoc($result)) {
			return (int)$row['count'];
		}
		return 0;
	}	
	
	/**
	 * @return int
	 */
	function getActiveOrganizationsCount() {
		global $App;
	
		$id = $this->getId();
		$result = $App->dashboard_sql("select count(distinct company) as count from ProjectCompanyActivity where project='$id'");

		while($row = mysql_fetch_assoc($result)) {
			return (int)$row['count'];
		}
		return 0;
	}
	
	/**
	 * Answers whether or not the receiver has recent commit activity.
	 * 
	 * @param int $months (Optional) how many months in the past to check.
	 * @return boolean
	 */
	function hasRecentCommitActivity($months = 6) {
		$activity = $this->getCommitActivity();
		$date = strtotime('now');
		while ($months) {
			if ($activity[date('Ym',$date)]) return true;
			$date = strtotime("-1 month", $date);
			$months--;
		}
		return false;
	}
	
	/**
	* Returns the commit activity for the receiver in the form of an 
	* array mapping period to commit count.
	*
	* e.g.,
	*
	* array('201001' => 52, '201002' => 33, ...)
	*
	* Note that this information is cached. The first time this method
	* is called (on any instance), the cache is created.
	*
	* @returns [] array mapping period to commit count.
	*/
	function getCommitActivity() {	
		if (isset($this->_commitActivity)) return $this->_commitActivity;
		
		global $App;
		
		$id = $this->getId();
		$result = $App->dashboard_sql("select period, count from ProjectCommitActivity where project='$id'");

		$this->_commitActivity = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_commitActivity[$row['period']] = $row['count'];
		}
		return $this->_commitActivity;
	}
	
	/**
	 * Returns the last three month's worth of company commit activity 
	 * for the receiver in the form of an array mapping company name to
	 * commit count.
	 * 
	 * e.g.,
	 * 
	 * array('IBM' => 52, 'Actuate Corporation' => 33)
	 * 
	 * Note that this information is cached. The first time this method 
	 * is called (on any instance), the cache is created.
	 * 
	 * @returns [] array mapping company name to commit count.
	 */
	function getCompanyCommitActivity() {		
		if (isset($this->_companyActivity)) return $this->_companyActivity;
		
		global $App;
		
		$id = $this->getId();
		$result = $App->dashboard_sql("select company, count from ProjectCompanyActivity where project='$id'");

		$this->_companyActivity = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_companyActivity[$row['company']] = $row['count'];
		}
		return $this->_companyActivity;
	}
	
	/**
	* Returns the last three month's worth of committer commit activity
	* for the receiver in the form of an array mapping committer name to
	* commit count.
	*
	* e.g.,
	*
	* array('Wayne Beaton' => 52, 'Doug Schaefer' => 33)
	*
	* Note that this information is cached. The first time this method
	* is called (on any instance), the cache is created.
	*
	* @returns [] array mapping company name to commit count.
	*/
	function getCommitterCommitActivity() {		
		if (isset($this->_committerActivity)) return $this->_committerActivity;
		
		global $App;
		
		$id = $this->getId();
		$result = $App->dashboard_sql("select login, count from ProjectCommitterActivity where project='$id'");

		$this->_committerActivity = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_committerActivity[$row['login']] = $row['count'];
		}
		return $this->_committerActivity;
	}
	
	function getLicenses() {
		global $App;
		
		$id = $this->getId();
		
		$sql = "select distinct LicenseId from ProjectLicenses where ProjectId='$id'";
		$result = $App->foundation_sql($sql);
		
		$licenses = array();
		while ($row = mysql_fetch_assoc($result)) {
			$licenses[] = $row['LicenseId'];
		}
		return $licenses;
	}
	
	/*
	 * This function assembles a collection of ProjectInfoValue instances
	 * for the given $key. Essentially, this is an object that represents
	 * a group of values in the receiver and presents a higher-level of
	 * abstraction for accessing those values.
	 * 
	 * Values are stored in the DB in a table like this:
	 * 
	 * +---------------+---------+-----------+----------------------------+
	 * | ProjectInfoID | MainKey | SubKey    | Value                      |
	 * +---------------+---------+-----------+----------------------------+
	 * |...            |         |           |                            |
	 * |8512           |newsgroup|name       |eclipse.examples.users      |
	 * |8512           |newsgroup|type       |main                        |
	 * |8512           |newsgroup|description|A useful newsgroup          |
	 * |9765           |newsgroup|name       |eclipse.examples.dev        |
	 * |9765           |newsgroup|type       |standard                    |
	 * |...            |         |           |                            |
	 * +---------------+---------+-----------+----------------------------+
	 * 
	 * These values are associated with the technology.examples project.
	 * 
	 * If we ask the Project instance to getNewsgroups(), this function will
	 * be invoked and find these five rows. It would, from these rows, create
	 * two instances of ProjectInfoValues: one representing the values for
	 * ProjectInfoID=8512, and a second representing the values for
	 * ProjectInfoID=9765. These instances can then be sent relatively 
	 * high-level messages like getName(), getType(), and getDescription()
	 * to obtain useful information.
	 * 
	 * PRIVATE: THIS FUNCTION IS NOT API.
	 */
	/* private */ function getProjectInfoValues($key) {
		$this->root->load_project_info();
		$infoValues = array();
		foreach($this->values as $value) {
			if ($value['MainKey'] == $key) {
				$id = $value['ProjectInfoID'];
				if (!isset($infoValues[$id])) $infoValues[$id] = new ProjectInfoValue($id, $key, $this);
			}
		}	
		return $infoValues;
	}
	
	/* private */ function findRows($mainkey) {
		$this->root->load_project_info();
		$rows = array();
		foreach($this->values as $row) {
			if ($row['MainKey'] == $mainkey) $rows[] = $row;
		}
		return $rows;
	}
	
	/* private */ function findFirstValue($mainkey, $subkey = '') {
		$this->root->load_project_info();
		foreach($this->values as $row) {
			if ($row['MainKey'] != $mainkey) continue;
			if ($row['SubKey'] != $subkey) continue;
			return trim($row['Value']);
		}
		return null;
	}
	
	/* private */ function findValues($mainkey, $subkey = '') {
		$values = array();
		$this->root->load_project_info();
		foreach($this->values as $row) {
			if ($row['MainKey'] != $mainkey) continue;
			if ($row['SubKey'] != $subkey) continue;
			$values[] = trim($row['Value']);
		}
		return $values;
	}
	
	function isCommitterEmail($address) {
		return true;	
	}
	
	function hasChildren() {
		return $this->children ? true : false;
	}
	
	function getChildren() {
		return $this->children;
	}
	
	/**
	 * Return the people associated with this project. Note that
	 * the value is cached so that subsequent calls return the
	 * same objects.
	 * 
	 * @return Committer[]
	 */
	function getPeople() {
		require_once dirname(__FILE__) . '/Committer.class.php';
		
		if ($this->people === null) 
			$this->people = getCommittersForProject($this->getId());
		
		return $this->people;
	}
	
	/**
	 * Answers <code>true</code> if the receiver's
	 * inherit flag is set (meaning that metadata from the
	 * parent should be inherited), or <code>false</code>
	 * otherwise.
	 */
	function inheritsFromParent() {
		return $this->findFirstValue('inherit', 'inherit');
	}
	
	/**
	 * This function will make sure that the given URL is likely valid by
	 * converting it (if necessary) into an absolute URL. It further checks
	 * to ensure that the URL is from an 'eclipse.org' property.
	 * 
	 * @deprecated Use normalizeFilePathUrl or normalizeHttpUrl
	 * @param A string value representing an absolute or relative URL.
	 * @return A likely valid absolute URL that references an eclipse.org page
	 */
	function normalizeProjectDescriptionUrl($url) {
		return $this->normalizeUrlAsHTTP($url);
	}
	
	/**
	 * This function normalizes the provided URL to an HTTP form. Input
	 * should be a valid eclipse.org URL or a relative URL (with or without
	 * a leading slash).
	 * 
	 * e.g. The following URLs will all normalize to 
	 * http://eclipse.org/woolsey/para.html
	 * 
	 * - http://www.eclipse.org/woolsey/para.html
	 * - http://eclipse.org/woolsey/para.html
	 * - http://localhost/woolsey/para.html
	 * - woolsey/para.html 
	 * - /woolsey/para.html)
	 * 
	 * Note that URLs that do not correspond to eclipse.org addresses, will
	 * result in a <code>null</code> result.
	 * 
	 * Usage: 
	 * 
	 * Project::normalizeHttpUrl('http://www.eclipse.org/woolsey/para.html');
	 * 
	 * @param String $url
	 * @deprecated Use normalizeHttpUrl($url) from common.php
	 */
	public function normalizeHttpUrl($url) {	
		return normalizeHttpUrl($url);
	}
	
	/**
	 * This function normalizes the provided URL to valid file path on the
	 * eclipse.org web directory. Input should be a valid eclipse.org URL 
	 * or a relative URL (with or without a leading slash).
	 * 
	 * e.g. The following URLs will all normalize to 
	 * /home/local/data/httpd/www.eclipse.org/html/woolsey/para.html
	 * 
	 * - http://www.eclipse.org/woolsey/para.html
	 * - http://eclipse.org/woolsey/para.html
	 * - http://localhost/woolsey/para.html
	 * - woolsey/para.html 
	 * - /woolsey/para.html)
	 * 
	 * Note that URLs that do not correspond to eclipse.org addresses, will
	 * result in a <code>null</code> result.
	 * 
	 * Usage: 
	 * 
	 * Project::normalizeFilePathUrl('http://www.eclipse.org/woolsey/para.html');
	 * 
	 * @param String $url
	 * @deprecated Use normalizeFilePathUrl($url) from common.php
	 */
	public function normalizeFilePathUrl($url) {
		return normalizeFilePathUrl($url);
	}
		
	/**
	 * This function normalizes the provided URL to a relative path. 
	 * Input should be a valid eclipse.org URL or a relative URL 
	 * (with or without a leading slash).
	 * 
	 * e.g. The following URLs will all normalize to 
	 * /woolsey/para.html
	 * 
	 * - http://www.eclipse.org/woolsey/para.html
	 * - http://eclipse.org/woolsey/para.html
	 * - http://localhost/woolsey/para.html
	 * - woolsey/para.html 
	 * - /woolsey/para.html)
	 * 
	 * Note that URLs that do not correspond to eclipse.org addresses, will
	 * result in a <code>null</code> result.
	 * 
	 * Usage: 
	 * 
	 * Project::extractcRelativeUrl('http://www.eclipse.org/woolsey/para.html');
	 * 
	 * @param string $url
	 * @deprecated Use normalizeRelativeUrl($url) from common.php
	 */
	public function normalizeRelativeUrl($url) {		
		return normalizeRelativeUrl($url);
	}
	
	/**
	 * PRIVATE - THIS IS NOT API.
	 * 
	 * This method cleans up the description by removing potentially harmful tags.
	 * 
	 * @param string $description
	 */
	function cleanDescription($description) {
		// If we've been given a phoenix page, extract out the interesting bits.
		if(preg_match('/\<div id="midcolumn"\>/s', $description)) {
			$description = preg_replace('/((^.*\<div id="midcolumn"\>)|(\<\/div\>\<div id="footer"\>.*))/s', '', $description);
			$description = substr($description, 0, strripos($description, '</div>'));
		}
		
		return $description;
	}
	
	/**
	 * This function extracts a short description from the provided (potentially)
	 * long one. We attempt to find the first paragraph in what we assume is HTML
	 * text. 
	 * 
	 * @param string $description The (potentially) long description, a string containing HTML.
	 * @param int $maxWords (optional) The maximum number of words in the result.
	 * @return string a string with limited HTML content (no surrounding 'p' tags).
	 */
	function extractShortDescription($description, $maxWords=100) {	
		// Match everything between the first <p> tag and the next </p> or <br> tag.	
		$matches = array();
		if (preg_match('/<p>(.*?)(?:(?:<\/p>)|(?:<br\s*\/?>))/s', $description, $matches)) {
			//print_r($matches);
			$description = $matches[1];
		}
		
		// Kill any tags that might occur in the text.
		$description = preg_replace('/<[^>]*>/', '', $description);
			
		// Restrict the word count in the result.
		$words = str_word_count($description, 2);
		if (count($words) > $maxWords) {
			$indices = array_keys($words);
			$description = substr($description, 0, $indices[$maxWords]) . '...';
		}
		
		return $description;
	}
}

/*
 * Each instance of this class represents a collection of values 
 * from the ProjectInfoValues table that share a common ProjectInfoID and MainKey. 
 * These values are actually stored in an array on the Project instance itself;
 * instances of this class do not store the values themselves, but rather
 * find the values on the Project instance.
 * 
 * Instances can be queried for the values of the various SubKeys in the
 * corresponding values using high-level function names. The function
 * getName(), for example, would return the value in the row with SubKey
 * 'name'.
 * 
 * For more information, see the comment on Project#getProjectInfoValues($key).
 * 
 * THIS CLASS IS NOT INTENDED TO BE INSTANTIATED BY CLIENTS.
 */
class ProjectInfoValue {
	var $id;
	var $key;
	var $project;
	
	function __construct($id, $key, $project) {
		$this->id = $id;
		$this->key = $key;
		$this->project = $project;
	}
	
	function __call($name, $args) {
		$match = array();
		if (preg_match('/^get(.*)$/', $name, $match)) {
			return $this->getValue($match[1]);
		}
	}
		
	/* private */ function getValue($subkey) {
		foreach ($this->project->values as $row) {
			if ($row['MainKey'] != $this->key) continue;
			if ($row['ProjectInfoID'] != $this->id) continue;
			if (strcasecmp($row['SubKey'], $subkey) == 0) return $row['Value'];
		}
		return null;
	}
}

/**
 * We never actually instantiate this class, it is provided to
 * expose API for values returned by the Project#getNewsgroups
 * method. Actual values are instances of ProjectInfoValue and
 * the methods indicated below work through reflection.
 */
abstract class Newsgroup {	
	abstract function getId();
	abstract function getName();
	abstract function getType();
	abstract function getDescription();
}


class Release {	
	var $project;
	var $name;
	var $date;
	
	function __construct($project, $data) {
		$this->project = $project;
		$this->data = $data;
		$name = $data->getValue('name');
		if (preg_match('/(\d+)(\.\d+)?(\.\d+)?[\s\_\-\.]*((M|RC)\d+)?/', $name, $matches)) {
			$name = $matches[1];
			$name .= isset($matches[2]) && $matches[2] ? $matches[2] : '.0';
			$name .= isset($matches[3]) && $matches[3] ? $matches[3] : '.0';
			if (isset($matches[4]) && $matches[4]) $name .= $matches[4];
			$this->name = $name;
		} 
		$this->date = strtotime($data->getValue('date'));
	}
	
	function getReview() {
		foreach($this->project->getReviews() as $review) {
			if (!$review->isRelease()) continue;
			if ($review->getVersion() == $this->name) return $review;
		}
		return null;
	}
	
	function getName() {
		return $this->name;
	}
	
	function isValid() {
		if (!$this->name) return false;
		if (!$this->date) return false;
		if ($this->date < strtotime('2000-01-01')) return false;
		return true;
	}
	
	function isMilestone() {
		return preg_match('/((M|RC)\d+)$/', $this->name);
	}
	
	function getDate() {
		return $this->date;
	}
	
	/**
	 * Fetch the URL for the project plan for this release if it has
	 * been specified. Note that we try to be very forgiving about the format.
	 * 
	 * The following values will all result in a plan URL of "project/plan.xml"
	 * - http://www.eclipse.org/project/plan.xml
	 * - http://eclipse.org/project/plan.xml
	 * - http://www.eclipse.org/projects/project-plan.php?planurl=http://eclipse.org/project/plan.xml
	 * - http://www.eclipse.org/projects/project-plan.php?planurl=/project/plan.xml
	 * - http://www.eclipse.org/projects/project-plan.php?planurl=project/plan.xml
	 * 
	 * @return string
	 */
	function getPlan() {
		$plan = $this->data->getValue('plan');
		if (preg_match('/^(http:\/\/(www\.)?eclipse\.org\/projects\/project-plan\.php\?planurl=)?(http:\/\/(www\.)?eclipse.org)?\/?(.+\.xml)$/', $plan, $matches)) {
			return $matches[5];
		}
		return $plan;
	}
	
	function getStatus() {
		return $this->data->getValue('status');
	}
	
	function getNoteworthyUrl() {
		return $this->data->getValue('noteworthyurl');
	}
	
	function getDownload() {
		return $this->data->getValue('download');
	}
}

abstract class SourceRepository {
	var $project;
	var $path;
	
	function __construct($project, $path) {
		$this->project = $project;
		$this->path = $path;
	}
	
	function getName() {
		return $this->getPath();
	}
	
	function getPath() {
		return $this->path;
	}
	
	function providesCommitActivity() {
		return true;
	}
	
	function isReal() {
		// TODO test to see if the receiver represents a real repository.
		return true;
	}
	
	/**
	 * Get the repository-technology specific URL for the repository.
	 * e.g. git://git.eclipse.org/gitroot/jgit/jgit.git
	 */
	abstract function getUrl();
	abstract function getType();
	
	/**
	 * Return an HTTP link for the receiver. i.e. something that is suitable
	 * for a browser
	 */
	abstract function getLink();
}

class GitRepository extends SourceRepository {
	function getName() {
		if (preg_match('/org\.eclipse\.(.*)\.git$/', $this->path, $matches)) {
			return $matches[1];
		} else if (preg_match('/org\.eclipse\.(.*)$/', $this->path, $matches)) {
			return $matches[1];
		} else if (preg_match('/([^\/]*)\.git$/', $this->path, $matches)) {
			return $matches[1];		
		} else if (preg_match('/([^\/]*)$/', $this->path, $matches)) {
			return $matches[1];
		} else {
			return $this->path;
		}
	}
	
	function getPath() {
		return "/gitroot$this->path";
	}
	
	function getType() {
		return "git";
	}
	
	function getLink() {
		return "http://git.eclipse.org/c$this->path";
	}
	
	function getGitUrl() {
		return "git://git.eclipse.org/gitroot$this->path";
	}
	
	function getUrl() {
		return $this->getGitUrl();
	}
}

class EGitRepository extends GitRepository {	
	
	function getName() {
		return $this->getLink();
	}
	
	function getLink() {
		if (preg_match('/^git:\/\/(egit\.eclipse\.org\/.*)$/', $this->path, $matches)) {
			return 'http://' . $matches[1];
		}
		return $this->path;
	}
	
	function getPath() {
		return $this->getLink();
	}
	
	function getGitUrl() {
		return $this->path;
	}
	
	function providesCommitActivity() {
		return false;
	}
}

class CvsRepository extends SourceRepository  {
	function getType() {
		return "cvs";
	}
	
	function getPath() {
		return "/cvsroot$this->path";
	}
	function getLink() {
		preg_match('/^\/?\w+\/(.*)$/', $this->path, $matches);
		$root = $this->project->getTopLevelProject()->getId();
		if (strlen($root) <= 4) {
			$root = strtoupper($root);
		} else {
			$root = ucwords($root);
		}
		$path = $matches[1];
		return "http://dev.eclipse.org/viewcvs/viewvc.cgi/$path/?root=${root}_Project";
	}
	
	function getUrl() {
		if (preg_match('/^(\/cvsroot\/[^\/]+)\/(.+)$/', $this->getPath(), $matches)) {
			$repository = $matches[1];
			$path = $matches[2];
			
			return ":pserver:anonymous@dev.eclipse.org:$repository:$path";
		} else return null;
	}
}

class SvnRepository extends SourceRepository  {
	function getType() {
		return "svn";
	}
	
	/* private */ function isUppercaseRoot($root) {
		if ($root == 'modeling') return false;
		if ($root == 'technology') return false;
		return true;
	}
	
	function getLink() {
		preg_match('/^[^\/]*\/(.*)$/', $this->path, $matches);
		$root = $this->project->getTopLevelProject()->getId();
		if ($this->isUppercaseRoot($root)) {
			$root = strtoupper($root);
		} else {
			$root = ucwords($root);
		}
		$project = $this->project->getShortId();
		
		// Need to handle a few special cases...
		if ($project == 'swtbot') $project = 'SWTBot';
		else if ($project == 'g-eclipse') $project = 'GEclipse';
		else if ($project == 'eclipselink') $project = 'PERSISTENCE';
		else if ($project == 'dbaccess') $project = 'GEMINI.DBACCESS'; // Bug 369905
		else if ($project == 'naming') $project = 'GEMINI.NAMING';
		else if ($project == 'blueprint') $project = 'GEMINI.BLUEPRINT';
		else if ($project == 'jpa') $project = 'GEMINI.JPA';
		else $project = strtoupper($project);
		
		return "http://dev.eclipse.org/viewcvs/viewvc.cgi/?root=${root}_${project}";
	}
	
	function getUrl() {
		$path = $this->getPath();
		return "http://dev.eclipse.org$path";
	}
	
	function getPath() {
		return "/svnroot/$this->path";
	}
}

/**
 * Sort the array of projects by the given key. Valid keys
 * are 'name', or 'top' (top level project).
 * 
 * @param Project[] $projects
 * @param string $key
 */
function sortProjects(&$projects, $key = 'name') {
	if (!in_array($key, array('name', 'top'))) $key = 'name';
	
	return usort($projects, "_sortProjects_$key");
}

/* private */ function _sortProjects_name($a, $b) {
	return strcasecmp($a->getName(), $b->getName());	
}

/* private */ function _sortProjects_top($a, $b) {
	return strcasecmp($a->getTopLevelProject()->getName(), $b->getTopLevelProject()->getName());	
}

/**
 * This function answers an instance of SourceRepository corresponding to the
 * value of the parameter.
 * 
 * Example:
 * 
 * getSourceRepository('/gitroot/woolsey/org.eclipse.woolsey.iplog.git')
 *  returns an instance of GitRepository
 *  
 * @see SourceRepository
 * @see GitRepository
 * @see EGitRepository
 * @see CvsRepository
 * @see SvnRepository
 *
 * @param string $repository
 * @return SourceRepository
 */
function getSourceRepository($repository, $project=null) {
	global $projectNamePattern;
	
	// We only care about source code repositories, skip websites.
	if (preg_match('/org\.eclipse\/www/', $repository)) return null;
	
	// EGit is a special case.
	if (preg_match('/^git:\/\/egit\.eclipse\.org(\/.*)$/', $repository)) return new EGitRepository($project, $repository);

	// Deal with Git. 
	if (preg_match('/\/gitroot((\/[\w\.\-]+)+)\/?$/', $repository, $matches)) return new GitRepository($project, $matches[1]);
	if (preg_match('/^http:\/\/git\.eclipse\.org\/c(\/.*)$/', $repository)) return new GitRepository($project, $matches[1]);
	
	// Deal with CVS.
	if (preg_match('/^\/cvsroot((\/[\w\-\.]+)+)\/?$/', $repository, $matches)) return new CvsRepository($project, $matches[1]);
	
	// Deal with SVN.  
	if (preg_match('/^(\/?svnroot)?\/?(\w+(\/[\w\-\.]+)+)\/?$/', $repository, $matches)) return new SvnRepository($project, $matches[2]);
	return null;
}

?>