<?php
/*******************************************************************************
 * Copyright (c) 2010, 2017 Eclipse Foundation and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 ********************************************************************************/

require_once (dirname(__FILE__) . "/Forge.class.inc");
require_once (dirname(__FILE__) . "/License.class.inc");
require_once (dirname(__FILE__) . "/database.inc");
require_once (dirname(__FILE__) . "/debug.php");
require_once (dirname(__FILE__) . "/common.php");

define('PROJECT_LIVELINESS_NEVER_ACTIVE', 0);
define('PROJECT_LIVELINESS_ACTIVE', 1);
define('PROJECT_LIVELINESS_STALE', 2);
define('PROJECT_LIVELINESS_INACTIVE', 2);
define('PROJECT_LIVELINESS_DEAD', 4);

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

define('TRADEMARK_REGISTERED', 1);
define('TRADEMARK_UNREGISTERED', 2);
define('TRADEMARK_FILED', 3);

define('TRADEMARK_ALL', TRADEMARK_REGISTERED | TRADEMARK_UNREGISTERED);

/**
 * Get a project from the PMI instead of the foundation database.
 * Going directly to the PMI is no longer necessary now that the
 * implementation has been cleaned up. Now, we can just load the
 * project; if information is required from the PMI, it will be
 * loaded from there.
 *
 * @deprecated use Project::getProject()
 * @param string $id
 *        a project id of the form 'technology.egit'
 * @return PMIProject
 */
function get_project_from_pmi($id) {
  return Project::getProject($id);
}

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

/**
 * Instances of the subclasses of Project represent a single Eclipse Foundation
 * Project.
 * Projects may be in any of the forges supported by the Eclipse
 * Foundation.
 *
 * This class has two subclasses. The ProductProxy class is basically the
 * entry-point; when you ask for a project, you first get one of these. These
 * instances are pretty cheap to make and can answer a lot of questions. When
 * requests are made that require more information, that information is
 * gathered from the PMI and results in the creation of a PMIProduct instance
 * (loading from the PMI is pretty expensive, so we try to avoid it when we
 * can).
 *
 * The entry points are all static methods on this class. Instances should
 * never be created using the constructors.
 *
 * Note that instances are cached as they are loaded; subsequent queries
 * will always return the cached instance.
 */
abstract class Project {
  static $config;
  static $projects = array();

  /**
   * Initialize the class by loading the configuration from
   * projects.ini. The projects.ini file includes information about
   * how projects have moved (e.g. 'technology.ecf' became 'rt.ecf'),
   * information about Top Level Project specific brands, etc.
   */
  static function init() {
  	self::$config = parse_ini_file(dirname(__FILE__) . '/projects.ini');
  }

  /**
   * Get all projects regardless of whether or not they are active
   * or archived. The Foundation database is used to get this information.
   * This implementation takes project moves that occurred in the day
   * when we duplicated information (e.g. there are records in the
   * database for 'technology.ecf' and 'rt.ecf') into consideration.
   * A project that has been moved will only be represented once in
   * this query.
   *
   * This move information is represented in the projects.ini file.
   *
   * Other pseudo projects are also skipped by this query.
   *
   * @return ProjectProxy[]|mixed[]
   */
  public static function getAll() {
  	// Skip all pseudo projects.
  	$skip = array("'root'", "'foundation-internal'", "'galileo'");

  	// Skip all projects that were duplicated in a move operation.
  	// TODO Consider encapsulating this access of the static field.
  	foreach(self::$config['move'] as $from => $to) {
  		$skip[] = "'{$from}'";
  	}
  	$skip = implode(',', $skip);
    return self::getProjects(array(
      "IsComponent = 0",
      "(p.ProjectID not in ($skip))",
      "(p.ParentProjectID not in ('foundation-internal'))"
    ));
  }

  public static function getProject($id) {
    if (!isValidProjectId($id))
      return null;
    $projects = self::getProjects(array(
      "(p.ProjectId = '$id')"
    ));
    if ($projects)
      return $projects[$id];
    return null;
  }

  public static function getAllProjects($ids) {
    $all = array();
    foreach($ids as $id) {
    	if (isValidProjectId($id)) {
    		$all[] = "'{$id}'";
    	}
    }
    $all = implode(',', $all);
    return self::getProjects(array(
    	"(p.ProjectId in ($all))"
    ));
  }

  private static function getAlternateForgeIds() {
    $forges = array();
    foreach (Forge::getForges() as $forge) {
      if (!$forge->isEclipseForge())
        $forges[] = "'{$forge->getId()}'";
    }
    return implode(',', $forges);
  }

  public static function getTopLevelProjects() {
    $forges = self::getAlternateForgeIds();
    $where = array(
		"p.IsActive",
      	"(p.ProjectID not in ('root', 'foundation-internal', 'galileo'))",
		"(p.ParentProjectID not in ('foundation-internal'))");
    if ($forges)
		$where[] = "((p.ParentProjectID = 'root' and p.ProjectId not in ($forges)) or p.ParentProjectID in ($forges))";
    else
    	$where[] = "p.ParentProjectID = 'root'";

    return self::getProjects($where);
  }

  public static function getActiveProjects() {
    $forges = self::getAlternateForgeIds();
    $where = array(
    		"p.IsActive",
    		"(p.ProjectID not in ('root', 'foundation-internal', 'galileo'))",
    		"(p.ParentProjectID not in ('foundation-internal'))");
    if ($forges)
    	$where[] = "(p.ProjectId not in ($forges))";

    return self::getProjects($where);
  }

  public static function getProjectsForCommitter($id) {
    $forges = self::getAlternateForgeIds();
    $where = array(
    		"(p.ProjectID in (SELECT ProjectID FROM PeopleProjects where PersonId='$id' and Relation='CM' and InactiveDate is null))",
    		"p.IsActive"
    );
    if ($forges)
    	$where[] = "(p.ProjectId not in ($forges))";

    return self::getProjects($where);
  }

  /**
   * This function answers an array containing all those projects that
   * use the license with the provided id.
   *
   * @param string $id the license id as expressed in the Foundation DB (e.g. 'EPL-2.0')
   * @return Project[]
   */
  public static function getProjectsWithLicense($id) {
   return self::getProjects(array(
     "p.ProjectId in (select ProjectId from ProjectLicenses where LicenseId='{$id}')",
     "p.IsActive"
   ));
  }

  public static function getSubprojects($id) {
    return self::getProjects(array(
      "(p.ParentProjectId = '$id')",
      "p.IsActive"
    ));
  }

  public static function visit($callable, $pre = null, $post = null) {
    if ($pre) call_user_func($pre, null);
    foreach (self::getTopLevelProjects() as $project) {
      $project->visitHierarchy($callable, $pre, $post, 0);
    }
    if ($post) call_user_func($post, null);
  }

  private static function getProjects($conditions) {
    $where = join(' and ', $conditions);

    $sql = "
            SELECT distinct
                p.ProjectId as id, p.Name as name, p.ParentProjectID as parent, p.ProjectPhase as phase,
                p.UrlDownload,
                group_concat(distinct l.LicenseId) as licenses,
                min(pp.ActiveDate) as provisioned_date,
                group_concat(distinct cm.PersonId) as committer_ids,
                group_concat(distinct pl.PersonId) as lead_ids
            FROM Projects as p
                left join ProjectLicenses as l on p.ProjectId=l.ProjectId
                left join PeopleProjects as pp on p.ProjectId=pp.ProjectId
                left join PeopleProjects as cm on p.ProjectId=cm.ProjectId and cm.Relation='CM' and cm.InactiveDate is null
                left join PeopleProjects as pl on p.ProjectId=pl.ProjectId and pl.Relation='PL' and pl.InactiveDate is null
            where
                $where
            group by p.ProjectId";

    $projects = array();
    query('foundation', $sql, null, function ($row) use (&$projects) {
      $id = $row['id'];
      if (isset(Project::$projects[$id])) {
        $projects[$id] = Project::$projects[$id];
      }
      else {
        $project = new ProjectProxy($id, $row);
        Project::$projects[$id] = $project;
        $projects[$id] = $project;
      }
    });

    // The configuration defines projects that should be removed
    // from query results. Remove those projects.
    // TODO Consider encapsulating this access of the static field.
    foreach(self::$config['remove'] as $remove) {
    	unset($projects[$remove]);
    }

    return $projects;
  }

  private function __construct() {
  }

  /**
   * Answer the raw name of the receiver. This is
   * the name as it appears in the data. We almost
   * never want to use this directly. Instead, use
   * the nick name or formal name.
   *
   * @see Project::getNickName()
   * @see Project::getFormalName()
   */
  public abstract function getName();

  public abstract function getId();

  public abstract function getParentId();

  public abstract function getProjectPhase();

  public abstract function getProxy();

  /**
   * The short id is the last segment in the fully-qualified
   * id. e.g. the short id of 'technology.egit' is 'egit'.
   *
   * @return string
   */
  public function getShortId() {
   preg_match("/([^\.]+)$/", $this->getId(), $matches);
   return $matches[1];
  }

  public function getLocalId() {
    return $this->getForge()->getLocalProjectId($this->getId());
  }

  public function getShortName() {
    return $this->getName();
  }

  public function getChildren() {
    return self::getSubprojects($this->getId());
  }

  public function getParent() {
    return self::getProject($this->getParentId());
  }

  public function isInIncubationPhase() {
    return in_array($this->getProjectPhase(), array(
      'Incubation',
      'Incubation.nc'
    ));
  }

  /**
   * Components are an old concept.
   * Nothing is a component anymore.
   *
   * @return boolean Always false
   */
  public function isComponent() {
    return false;
  }

  public function isArchived() {
    return $this->getProjectPhase() == 'Archived';
  }

  public function isInIncubationConformingPhase() {
    return $this->getProjectPhase() == 'Incubation';
  }

  public function isInIncubationNonConformingPhase() {
    return false;
  }

  public function getUrl() {
    $id = $this->getLocalId();
    $base = $this->getForge()->getUrl();
    return "{$base}/projects/{$id}";
  }

  /**
   * This function answers the URL to use to get more data
   * about the project in JSON format, including releases, etc.
   */
  public function getDataUrl() {
	if (!$forge = Forge::getForgeForProjectId($this->getId())) {
		return null;
	}
	$base = $forge->getUrl();
	$local = $forge->getLocalProjectId($this->getId());
	return "{$base}/json/project/$local";
  }

  public function getTopLevelProject() {
    if ($this->isTopLevel())
      return $this;
    if (!$parent = $this->getParent())
      return $this;
    return $parent->getTopLevelProject();
  }

  public function isTopLevel() {
    if (!$forge = $this->getForge())
      return true;
    if ($forge->isEclipseForge())
      return $this->getParentId() == 'root';
    return $this->getParentId() == $forge->getId();
  }

  public function getForge() {
    return Forge::getForgeForProjectId($this->getId());
  }

  public function visitHierarchy($function, $pre = null, $post = null, $level) {
    call_user_func($function, $this, $level);
    if ($pre) call_user_func($pre, $this);
    foreach ($this->getChildren() as $child) {
      $child->visitHierarchy($function, $pre, $post, $level + 1);
    }
    if ($post) call_user_func($post, $this);
  }

  /**
   * This method answers the formal name of the project. If the
   * project's name does not include either 'Eclipse', or the
   * brand name associated with its Top Level Project, then the
   * brand name is prepended to the project name.
   *
   * Remove anything that's between parentheses. We actually
   * look for a space followed by an open parenthesis, because
   * some projects (e.g. "Eclipse e(fx)clipse") include them
   * in their proper name (and "Eclipse eclipse" just looks weird).
   *
   * e.g.
   * <li>"EGit" becomes "Eclipse EGit"</li>
   * <li>"e(fx)clipse" becomes "Eclipse e(fx)clipse"</li>
   * <li>"Eclipse Communication Framework (ECF)" becomes "Eclipse Communication Framework"</li>
   * <li>"PolarSys Capella" becomes "PolarSys Capella"</li>
   * <li>"Capella" becomes "PolarSys Capella"</li>
   *
   * @see Project::getNickName()
   *
   * @return string
   */
  public function getFormalName() {
  	$brand = $this->getBrandName();

    $name = trim(preg_replace('/ \([^\)]*\)/', ' ', $this->getName()));
    if (!preg_match("/(?:$brand|Eclipse)/", $name)) {
    	return "$brand $name";
    }
    return $name;
  }

  /**
   * Sort out the project's brand. If the project name starts with one of our brands,
   * as defined in the projects.ini file, then that is the project's brand.
   * The project's brand might also be determined by the top-level project
   * (a top-level project may have a brand associated with it; in this case,
   * all projects that fall under that top-level project use that brand.
   *
   * @return string
   */
  public function getBrandName() {
  	foreach(@self::$config['brands'] as $brand) {
  		if (preg_match("/^{$brand}/", $this->getName())) return $brand;
  	}

  	if ($brand = @self::$config['tlp'][$this->getTopLevelProject()->getId()])
  		return $brand;
  	return 'Eclipse';
  }

  /**
   * This method answers the nickname for the project.
   * The name of the project as listed in the foundation database is the best
   * source of this information. This is difficult to guess as sometimes the
   * forge name is part of the nick name and sometimes it's not. Values are
   * stored in the foundation database as the nickname with optional acronym in
   * parentheses. This method strips anything in parentheses from the returned
   * value.
   *
   * We actually look for a space followed by an open parenthesis, because
   * some projects (e.g. "Eclipse e(fx)clipse") include them
   * in their proper name (and "Eclipse eclipse" just looks weird).
   *
   * @see Project::getFormalName()
   *
   * @return string
   */
  public function getNickName() {
    // We get the proxy and ask it for the name.
    return trim(preg_replace('/ \([^\)]*\)/', ' ', $this->getProxy()->getName()));
  }

  /**
   *
   * @deprecated
   *
   * @return NULL
   */
  public function getNoteworthyUrl() {
    return null;
  }

  /**
   *
   * @deprecated
   *
   */
  public function getNewsgroups() {
    return array();
  }

  /**
   *
   * @deprecated
   *
   * @return null|Proposal
   */
  public function getProposal() {
    // FIXME Implement. Or don't.
    return null;
  }

  public function getLiveliness() {
    if (!$this->getCommitActivity())
      return PROJECT_LIVELINESS_NEVER_ACTIVE;
    if ($this->hasRecentCommitActivity(3))
      return PROJECT_LIVELINESS_ACTIVE;
    if ($this->hasRecentCommitActivity(6))
      return PROJECT_LIVELINESS_STALE;
    if ($this->hasRecentCommitActivity(12))
      return PROJECT_LIVELINESS_INACTIVE;

    return PROJECT_LIVELINESS_DEAD;
  }

  /**
   * Answers whether or not the receiver has recent commit activity.
   *
   * @param int $months
   *        (Optional) how many months in the past to check.
   * @return boolean
   */
  public 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.
   */
  public function getCommitActivity() {
    if (isset($this->_commitActivity))
      return $this->_commitActivity;

    $id = $this->getId();
    $sql = "select period, count from ProjectCommitActivity where project='$id'";

    $this->_commitActivity = array();
    query('dashboard', $sql, array(), function ($row) {
      $this->_commitActivity[$row['period']] = $row['count'];
    });
    return $this->_commitActivity;
  }
}

/**
 * This class implements a lightweight stand-in to represent a
 * project.
 * The basic idea is that it is far less expensive to
 * query the Foundation Database for information about projects
 * than it is to query the PMI. However, the PMI has a lot more
 * information. Instances of this class provide as much information
 * as they can, but then defer to the PMI when more information is
 * required.
 *
 * @see Project
 */
class ProjectProxy extends Project {
  private $id;
  private $data;
  private $project;

  public function __construct($id, $data) {
    $this->id = $id;
    $this->data = $data;
  }

  public function __toString() {
    return "Project ({$this->getId()})";
  }

  public function getId() {
    return $this->id;
  }

  public function getParentId() {
    return $this->data['parent'];
  }

  public function getProxy() {
    return $this;
  }

  public function getName() {
   return preg_replace ( '/ Root$/', '', $this->data ['name'] );
  }

  public function getProjectPhase() {
    return $this->data['phase'];
  }

  /**
   * We don't directly track the date of project provisioning.
   * Rather, we leverage a feature of the provisioning process by
   * which the provisioning process is triggered when the first
   * committer is ready to be assigned to the project (this is
   * figured into the query that we pull from the Foundation DB).
   *
   * This function returns our best guess at the provisioning date
   * in UNIX date format, or null if no such date can be determined.
   *
   * @see Project::getProjects
   * @return NULL|number
   */
  public function getProvisionedDate() {
    if (!isset($this->data['provisioned_date'])) return null;
    return strtotime($this->data['provisioned_date']);
  }

  public function hasProjectLeads() {
    return !empty($this->data['lead_ids']);
  }

  public function hasCommitters() {
  	return !empty($this->data['committer_ids']);
  }

  public function getSpecificationWorkingGroupName() {
  	$apiData = $this->getAPIData();
  	return @$apiData[0]['spec_project_working_group']['name'];
  }

  public function isSpecificationProject() {
  	$apiData = $this->getAPIData();
  	return !empty($apiData[0]['spec_project_working_group']);
  }

  /**
   * Get the data related to this project from the Eclipse API.
   *
   * @return array|mixed
   */
  private function getAPIData() {
  	if (@$this->apiData === NULL) {
	  	$url = 'https://projects.eclipse.org/api/projects/' . preg_replace('/\./','_',$this->getId());
	  	$ch = curl_init();
	  	curl_setopt($ch, CURLOPT_URL, $url);
	  	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	  	$this->apiData = json_decode(curl_exec($ch), true);
	  	curl_close($ch);
	  	if (!$this->apiData) $this->apiData = array();
  	}
  	return $this->apiData;
  }

  /**
   *
   * @deprecated
   * @return License[]
   */
  public function getLicenses() {
   return License::getLicensesForProject($this->getId());
  }

  /**
   * Answer a statement (suitable for use in a file header)
   * that describes the licenses of the project.
   *
   * @deprecated Use License::getLicensesStatement
   * @return string
   */
  public function getLicensesStatement() {
   return License::getLicensesStatement($this->getLicenses());
  }

  /**
   * @deprecated Use License::getSPDXLicenseExpression
   * @return string
   */
  public function getSPDXLicenseExpression() {
   return License::getSPDXExpression($this->getLicenses());
  }

  /**
   * @deprecated Use License::getDefaultFileHeader
   * @return string
   */
  public function getDefaultFileHeader() {
   return License::getDefaultFileHeader($this->getLicenses());
  }

  /**
   * @deprecated Use License::getAlternativeFileHeader
   * @return string
   */
  public function getAlternativeFileHeader() {
   return License::getAlternativeFileHeader($this->getLicenses());
  }

  /**
   * Answers an array containing the trademarks that are known
   * to be associated with the project.
   *
   * @return string[]
   */
  function getTrademarks($type = TRADEMARK_ALL, $includeForge = false) {
   $trademarks = array();
   if ($type & TRADEMARK_UNREGISTERED) {
     $this->trademarksDo($type, function($value) use (&$trademarks) {
       $trademarks[] = $value;
     });
   }
   return $trademarks;
  }

  /**
   * Iterate over the trademarks that are known to be associated
   * with the project.
   *
   * The primary source of information is the name of the project
   * as it is represented in the Foundation Database. If the project
   * name includes something in parentheses, then this implementation
   * assumes that something is a nickname or alternative name. Or, if there
   * are two names separated by <space><dash><space> they are treated
   * as separate names.
   *
   * Further, the configuration (projects.ini) defines zero or more "brands"
   * (e.g. 'LocationTech' or 'PolarSys') that are connected to a particular
   * Top Level Project. When the brand applies to a project and is not
   * already represented in the name, the brand is prepended to the name.
   * 'Eclipse' is the default brand.
   *
   * The number of trademarks that may be associated with a project
   * is open-ended. The callable may be executed any number (or zero)
   * times.
   *
   * e.g.
   * <li>'LocationTech GeoGig' maps to 'LocationTech GeoGig'</li>
   * <li>'GeoGig' maps to 'LocationTech GeoGig' and 'GeoGig'</li>
   * <li>'Eclipse EMF' maps so 'EMF'</li>
   * <li>'EMF' maps to 'Eclipse EMF' and 'EMF'</li>
   *
   * @see Project::init()
   * @see Project::normalizedTrademarksDo()
   *
   * @param string $type TRADEMARK_REGISTERED | TRADEMARK_UNREGISTERED
   * @param callable $function Function that takes a single argument.
   */
  function trademarksDo($type, $function) {
   if (preg_match('/(?:releng|website)$/', $this->getId())) return;
   $name = $this->getName();

   // TODO Deal with different trademark types.

    if (preg_match('/^([^\\(]+)\s\\(([^\\)]+)\\)/', $name, $matches)) {
     $this->normalizedTrademarksDo($function,$matches[1]);
     $this->normalizedTrademarksDo($function,$matches[2]);
    } elseif (preg_match('/^([^-]*)\s\\-\s([^-]*)$/', $name, $matches)) {
     $this->normalizedTrademarksDo($function,$matches[1]);
     $this->normalizedTrademarksDo($function,$matches[2]);
    } else {
     $this->normalizedTrademarksDo($function,$name);
    }

    if ($extra = @$this::$config['trademarks'][$this->getId()]) {
    	call_user_func($function, $extra);
    }
  }

  /**
   * Execute the function with each of the normalized trademarks extracted
   * from a term. The normalized trademarks for a particular
   * term are the term itself, along with the term prefixed
   * (if it does not already include) with the corresponding brand.
   *
   * e.g.
   * <li>"EclipseLink" normalizes as "EclipseLink"
   * <li>"EGit" normalizes as "EGit" and "Eclipse EGit"
   * <li>"Capella" normalizes as "Capella" and "PolarSys Capella"
   *
   * This script uses the branding information provided in
   * the project.ini file to map the Top Level project of the
   * receiver to a brand (default is "Eclipse").
   *
   * @see Project::getBrandName()
   * @see Project::getFormalName()
   * @see ProjectProxy::trademarksDo()
   *
   * @param callable $function
   * @param string $term The project name (e.g. 'EGit')
   */
  private function normalizedTrademarksDo($function, $term) {
  	$term = trim($term);
  	if (empty($term)) return;
  	$term = preg_replace('/\s?\\[[^\\]]*\\]/','', $term);

	// First check to see if the name uses one of the general brands;
	// if so, then that's the project name. When one of the general
	// brands does not apply, check for use of the TLP-specific
	// brand; when that brand is not present, both the name from the
	// database and that name prepended with the TLP-specific brand
	// are considered trademarks.
  	$brands = @self::$config['brands'];
  	$brands=implode('|', $brands);
	if (preg_match("/^(?:{$brands})/", $term)) {
  		call_user_func($function, "{$brand} {$term}");
	} else {
		$brand = $this->getBrandName();
		if (!preg_match("/(?:{$brand})/", $term)) {
			call_user_func($function, "{$brand} {$term}");
		}
		call_user_func($function, $term);
	}
  	return;
  }

  public function getDownloadUri() {
    if (!$url = $this->data['UrlDownload'])
      return null;
      // TODO We should probably ask the forge for the downloadUrl
    $forge = $this->getForge()->getId();
    if (!preg_match("/^https?:\/\/download.{$forge}.org\/(.*)$/", $url, $matches))
      return null;
    return $matches[1];
  }

  public function __call($name, $arguments) {
    if (!$project = $this->getPMIProject())
      return null;
    return call_user_func_array(array(
      $project,
      $name
    ), $arguments);
  }

  private function getPMIProject() {
    if ($this->project === null) {
      $project = PMIProject::getProject($this->getId());
      $this->project = $project ? $project : FALSE;
    }
    return $this->project;
  }

}

/**
 * Representation of an Eclipse Foundation project with information
 * obtained from a PMI instance.
 * Instances of this class should rarely
 * be made directly; use the static methods on Project to obtain
 * instances.
 *
 * @see Project
 */
class PMIProject extends Project {
  private $data;
  private $forge;
  private static $cache = array();

  /**
   * Obtain an representation of a project from a PMI instance.
   *
   * This method should not generally be used directly. Instead,
   * use the static methods on Project to obtain a reference to a project
   * and that reference will make this call if it is required.
   *
   * @param string $id
   * @return NULL|PMIProject
   */
  public static function getProject($id) {
    if (isset(self::$cache[$id]))
      return self::$cache[$id];

    if (!$forge = Forge::getForgeForProjectId($id))
      return null;
    $base = $forge->getUrl();
    $local = $forge->getLocalProjectId($id);
    $url = "{$base}/json/project/$local";

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $json = curl_exec($ch);
    curl_close($ch);

    if (!$json)
      return null;

    if (!$all = json_decode($json, true))
      return null;
    if (!$data = $all['projects'][$local])
      return null;

    return new PMIProject($data, $forge);
  }

  /**
   * @deprecated
   */
  public static function preload() {
  }

  private function __construct($data, $forge) {
    $this->data = $data;
    $this->forge = $forge;
  }

  /**
   * Answer the project's id as it appears in the Foundation Database.
   * The PMI data contains the local id. If the project comes from an
   * alternate forge, then the forge id is prepended to the local value.
   *
   * @return string
   */
  public function getId() {
    return $this->getForge()->getFoundationDBId($this->getLocalId());
  }

  public function getLocalId() {
    return $this->data['id'][0]['value'];
  }

  public function getForge() {
    return $this->forge;
  }

  public function getProxy() {
    // TODO Consider caching this value
    return Project::getProject($this->getId());
  }

  public function getName() {
    // TODO Get the name (when it's available)
    return $this->data['title'];
  }

  public function getDescription() {
    if (!$field = @$this->data['description'][0])
      return null;
    if (!empty($field['summary']))
      return $field['summary'];
    if (!empty($field['safe_value']))
     return $field['safe_value'];
    $value = $field['value'];
    $paragraphs = explode("\n", $value);
    return $paragraphs[0];
  }

  public function getScope() {
    if (!$field = @$this->data['scope'][0])
      return null;
    if (!empty($field['summary']))
      return $field['summary'];
    return @$field['safe_value'];
  }

  /**
   * Answer the project phase.
   * In the PMI, this is represented in
   * the "state" field. Two out of three values match what we do
   * in the Foundation Database. For the third, "Incubating", we
   * change it "Incubation" for consistency.
   *
   * @return string
   */
  public function getProjectPhase() {
    $state = $this->data['state'][0]['value'];
    if ($state == 'Incubating')
      return 'Incubation';
    return $state;
  }

  public function getDevListUrl() {
    return $this->data['dev_list']['url'];
  }

  public function getPlanUrl() {
    return @$this->data['plan_url'][0]['url'];
  }

  public function getWikiUrl() {
    return @$this->data['wiki_url'][0]['url'];
  }

  public function getDocumentationUrl() {
    return @$this->data['documentation_url'][0]['url'];
  }

  public function getDownloadsUrl() {
    return @$this->data['download_url'][0]['url'];
  }

  public function getGettingStartedUrl() {
    return @$this->data['gettingstarted_url'][0]['url'];
  }

  /**
   * Answer an array containing information about the source
   * repositories registered for the project.
   *
   * @return SourceRepository[]
   */
  public function getSourceRepositories() {
    $repositories = array();
    foreach ($this->data['source_repo'] as $repo) {
      $repositories[] = new SourceRepository($this, $repo);
    }
    return $repositories;
  }

  public function getBugzillaProduct() {
    foreach ($this->data['bugzilla'] as $record) {
      if (strlen($record['product']) > 0)
        return $record['product'];
    }
    return null;
  }

  public function getBugzillaComponents() {
    $components = array();
    foreach ($this->data['bugzilla'] as $record) {
      if (strlen($record['component']) > 0)
        $components[] = $record['component'];
    }
    return $components;
  }

  public function getMailingLists() {
    // FIXME Implement this
    return array();
  }

  /**
   * Answer the project's parent's id as it appears in the Foundation Database.
   * The PMI data contains the local id. If the project comes from an
   * alternate forge, then the forge id is prepended to the local value.
   *
   * @return string
   */
  public function getParentId() {
    return $this->getForge()->getFoundationDBId(@$this->data['parent_project'][0]['id']);
  }

  /**
   *
   * @deprecated
   *
   * @return string
   */
  function getProjectUrl() {
    return $this->getUrl();
  }

  /**
   * Answer an array of information regarding project releases.
   *
   * @return PMIRelease[]
   */
  function getReleases() {
    $releases = array();
    if (isset($this->data['releases'])) {
      foreach ($this->data['releases'] as $data) {
        $releases[] = new PMIRelease($this, $data);
      }
    }
    return $releases;
  }

  public function getReviews() {
    // FIXME Consider implementing this.
    return array();
  }

  /**
   * Answers the release that falls after a particular time.
   * If a date is not provided in the parameter, the current
   * date and time is assumed.
   *
   * @param int $time
   *        UNIX date.
   */
  public function getNextRelease($since = null) {
    if (!$since)
      $since = time();
    $releases = $this->getReleases();
    usort($releases, function ($a, $b) {
      return $a->getDate() == $b->getDate() ? 0 : ($a->getDate() < $b->getDate() ? -1 : 1);
    });

    foreach ($releases as $release) {
      if ($release->getDate() > $since)
        return $release;
    }

    return null;
  }

}
class PMIRelease {
  private $project;
  private $data;

  function __construct($project, $data) {
    $this->project = $project;
    $this->data = $data;
  }

  public function getTitle() {
    return $this->data['title'];
  }

  public function getName() {
    return $this->getTitle();
  }

  /**
   * Answers the UNIX date of the release.
   *
   * @return int
   */
  public function getDate() {
    foreach ($this->data['date'] as $data) {
      return strtotime($data['value']);
    }
    return null;
  }

  /**
   * Answers the URL for the release record.
   * If the information
   * is provided with the PMI data, then return that value. Otherwise,
   * make a very good guess at the value using the project URL and
   * the standard pattern for naming releases.
   *
   * Most of the time, the guess will be correct. But since the PMI
   * uses pathauto and there some cases where the project team e.g.
   * creates two releases with the same name, there is some risk that
   * the URL will be invalid. This risk is relatively low, however,
   * as we we usually (always?) have a URL from the PMI.
   *
   * @return string
   */
  public function getUrl() {
    if ($url = $this->data['url'])
      return $url;
    $url = $this->project->getUrl();
    $title = $this->getTitle();
    return "$url/releases/$title";
  }

  public function getNoteworthyUrl() {
    return @$this->data['noteworthy'][0]['url'];
  }
}

class SourceRepository {
  private $project;
  private $data;

  public function __construct($project, $data) {
    $this->project = $project;
    $this->data = $data;
  }

  /**
   * Answer the project that owns the reciever.
   *
   * @return Project
   */
  public function getProject() {
    return $this->project;
  }

  public function getName() {
    return $this->data['name'];
  }

  public function getPath() {
    return $this->data['path'];
  }

  public function providesCommitActivity() {
    return true;
  }

  public 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
   */
  public function getUrl() {
    return $this->data['url'];
  }

  public function getType() {
    return $this->data['type'];
  }

  /**
   * Return an HTTP link for the receiver.
   * i.e. something that is suitable
   * for a browser
   */
  public function getLink() {
    return $this->getUrl();
  }

}

/**
 * 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");
}

/**
 * Sort by Project name
 *
 * @internal
 *
 * @param Project $a
 * @param Project $b
 * @return number
 */
function _sortProjects_name($a, $b) {
  return strcasecmp($a->getName(), $b->getName());
}

/**
 * Sort project by Top Level Project.
 *
 * @internal
 *
 * @param Project $a
 * @param Project $b
 * @return number
 */
function _sortProjects_top($a, $b) {
  return strcasecmp($a->getTopLevelProject()->getName(), $b->getTopLevelProject()->getName());
}

// Initialize the class
Project::init();
?>