<?php
/*******************************************************************************
 * Copyright (c) 2010 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");

/**
 * Instances of the subclasses of Project represent a single Eclipse Foundation
 * Project.
 *
 * 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.
 */
class Project {
  static $config;
  static $projects = array();

  private $id;
  private $data;
  private $apiData = NULL;

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

  public static function getAllWithShortname($name) {
  	if (!isValidProjectId($name)) return null;

  	return self::getProjects(array(
  			"(p.ProjectId like '%.{$name}')",
  			"p.IsActive"
  	));
  }

  public static function getTopLevelProjects() {
    $where = array(
		"p.IsActive",
      	"(p.ProjectID not in ('root', 'foundation-internal', 'galileo'))",
		"(p.ParentProjectID not in ('foundation-internal'))",
    	"p.ParentProjectID = 'root'"
    );

    return self::getProjects($where);
  }

  public static function getActiveProjects() {
    $where = array(
    		"p.IsActive",
    		"(p.ProjectID not in ('root', 'foundation-internal', 'galileo'))",
    		"(p.ParentProjectID not in ('foundation-internal'))"
    );

    return self::getProjects($where);
  }

  public static function getProjectsForCommitter($id) {
    $where = array(
    		"(p.ProjectID in (SELECT ProjectID FROM PeopleProjects where PersonId='$id' and Relation='CM' and InactiveDate is null))",
    		"p.IsActive"
    );

    return self::getProjects($where);
  }

  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 Project($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;
  }


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

  /**
   * 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() {
   $matches = null;
   preg_match("/([^\.]+)$/", $this->getId(), $matches);
   return $matches[1];
  }

  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->getId();
    return "https://projects.eclipse.org/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() {
  	return 'https://projects.eclipse.org/api/projects/' . preg_replace('/\./','_',$this->getId());
  }

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

  public function isTopLevel() {
    return $this->getParentId() == 'root';
  }

  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';
  }

  /**
   * Answer an array containing information about the source
   * repositories registered for the project.
   */
  public function getSourceRepositories() {
  	$project = $this;
  	$repositories = array();
  	$sql = "select path from GitRepo where project=':id:'";
  	query('dashboard', $sql, array(':id:' => $this->getId()), function($row) use (&$project, &$repositories) {
  		$repositories[] = $row['path'];
  	});
  	return $repositories;
  }

  /**
   * Answers an array containing the trademarks that are known
   * to be associated with the project.
   *
   * @return mixed
   */
  function getTrademarks() {
  	$sql = "select name, demarcation, type from Trademark where category='project' and type is not null and id=':id:'";
  	$trademarks = array();
  	query('dashboard', $sql, array(':id:' => $this->getId()), function($row) use (&$trademarks) {
  		$trademarks[] = $row;
  	});
  		return $trademarks;
  }

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

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

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

  public function getName() {
  	$name = $this->data ['name'];
  	$name = preg_replace('/\s*\[archived\]\s*/','', $name);
   	$name = preg_replace ( '/ Root$/', '', $name);
   	return $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 getDescription() {
  	$apiData = $this->getAPIData();
  	return @$apiData[0]['description'];
  }

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

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

  public function getDevListUrl() {
  	$apiData = $this->getAPIData();
  	return @$apiData[0]['dev_list']['url'];
  }

  /**
   * Get the data related to this project from the Eclipse API.
   *
   * @return array|mixed
   */
  private function getAPIData() {
  	if ($this->apiData === NULL) {
	  	$url = $this->getDataUrl();
	  	$contents = getUrlContents($url);
	  	$this->apiData = json_decode($contents, true);
	  	// If we get empty data, make sure that it's not NULL, so that we
	  	// don't try again.
	  	if (!$this->apiData) $this->apiData = array();
  	}
  	return $this->apiData;
  }
}

/**
 * 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();
?>