<?php
/*******************************************************************************
 * Copyright (c) 2011 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 - initial API and implementation
 *******************************************************************************/

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

require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/Project.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/common.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/debug.php");
trace_file_info(__FILE__);

$_SimultaneousReleaseDates = array(
	'ganymede' => strtotime('2008-06-25'),
	'galileo' => strtotime('2009-06-24'),
	'helios' => strtotime('2010-06-23'),
	'indigo' => strtotime('2011-06-22'),
	'juno' => strtotime('2012-06-27'),
	'kepler' => strtotime('2013-06-26')
);

class SimultaneousReleaseInfo {
	/**
	 * The id of the project represented by the instance.
	 * @internal
	 * @var string
	 */
	var $id;
	
	var $release;
	
	/**
	 * Rows of data associated with this instance from the database.
	 * @internal
	 * @var string[][]
	 */
	var $rows;
	
	/**
	 * The id for any child projects that may be participating in 
	 * the release with the instance.
	 * @internal
	 * @var Project[]
	 */
	var $nested = array();
	
	function __construct($id, $release) {
		$this->id = $id;
		$this->release = $release;
	}
	
	function getId() {
		return $this->id;
	}
	
	function getProject() {
		return getProject($this->id);
	}
	
	function getOffset() {
		return $this->findRowValue('offset', '+0');
	}
	
	function getTentativeIpLogUrl() {
		$projects = array($this->getProject()->getId());
		foreach($this->nested as $nested) {
			$projects[] = $nested->getId();
		}
		
		return "http://eclipse.org/projects/ip_log.php?projectid=" . implode(',',$projects);
	}
	
	function getReleases() {
		global $_SimultaneousReleaseDates;
		if (!isset($_SimultaneousReleaseDates[$this->release])) return null;
		$before = strtotime('-1 week', $_SimultaneousReleaseDates[$this->release]);
		$after = $_SimultaneousReleaseDates[$this->release];
		$releases = $this->getProject()->getReleases();
		
		$found = array();
		foreach ($releases as $release) {
			if ($release->isMilestone()) continue;
			if ($release->getDate() < $before) continue;
			if ($release->getDate() > $after) continue;
			
			$found[] = $release;
		}
		return $found;		
	}
	
	/**
	 * Answers true if the receiver's project is new in this
	 * edition of the simultaneous release, or false otherwise.
	 */
	function isNew() {
		$releases = $this->getProject()->getSimultaneousReleaseNames();
		foreach(getSimultaneousReleaseNames() as $name) {
			if ($name == $this->release) return true;
			if (in_array($name, $releases)) return false;
		}
		return false;
	}
	
	/**
	 * 
	 * @return Project[]
	 */
	function getNested() {
		return $this->nested;
	}
	
	function findRowValue($key, $default = null) {
		$trace = trace("Searching for $key in " . $this->id);
		foreach($this->rows as $row) {
			$trace->trace("Checking " . $row['track_key']);
			if ($row['track_key'] == $key)
				return $row['track_value'];
		}
		$trace->trace("Not found!");
		return $default;
	}
}

function getAllSimultaneousReleaseInfo() {
	global $_SimultaneousReleaseInfo;
	_loadSimultaneousReleaseInfo($release);
	
	return $_SimultaneousReleaseInfo;
}

function getSimultaneousReleaseInfo($id, $release = null) {
	if (!$release) $release = getCurrentSimultaneousReleaseName();
	
	global $_SimultaneousReleaseInfo;
	_loadSimultaneousReleaseInfo($release);	
	
	// HACK.
	//if ($id == 'tools.sequoyah') $id = 'dsdp.sequoyah';
	
	if (!isset($_SimultaneousReleaseInfo[$release][$id])) return null;
	return 	$_SimultaneousReleaseInfo[$release][$id];
}

/**
 * Private - Load the SimultaneousReleaseInfo instances. This function
 * can be called multiple times; instances are loaded and cached on the
 * initial call.
 */
function _loadSimultaneousReleaseInfo($release) {
	global $App;
	global $_SimultaneousReleaseInfo;
	
	if ($_SimultaneousReleaseInfo[$release]) return;
	
	$trace = trace("Gather release train projects");
	$all = array();
	$info = array();
	$projects = getAllProjectsInSimultaneousRelease($release);
	foreach($projects as $project) {		
		$all[$project->getId()] = $info[$project->getId()] = new SimultaneousReleaseInfo($project->getId(), $release); 
	}
	
	$query = "select * from simultaneous_release_tracker";
	$result = $App->portal_sql($query);	
	while($row = mysql_fetch_assoc($result)){
		$nested = $trace->trace("Row");
		$id = $row['projectid'];
		if (!isset($info[$id])) continue;
		$info[$id]->rows[] = $row;
		
		foreach($row as $key => $value) {
			$nested->trace("$key > $value");
		}
	}
/*	
	foreach($all as $simultaneousRelease) {
		if (!$simultaneousRelease->rows) {
			$project = $simultaneousRelease->getProject();
			$parent = $project->getParent()->getId();
			$id = $project->getId();
			
			$trace->trace("Project $id is tracked by its parent $parent");
			
			$all[$parent]->nested[$id] = $project;
			unset($info[$id]);
		}
	}
*/	
	$query = "select projectid, tracked_by_projectid from simultaneous_release_tracker_project_relationships";
	$result = $App->portal_sql($query);

	while($row = mysql_fetch_assoc($result)){
		$id = $row['projectid'];
		$parent = $row['tracked_by_projectid'];
		
		$trace->trace("Project $id is tracked by its parent $parent");
		
		$all[$parent]->nested[$id] = getProject($id);
		unset($info[$id]);
	}
	
	$_SimultaneousReleaseInfo[$release] = $info;
}

/**
 * This function answers the names of all simultaneous releases.
 * The names are all in lowercase. Assuming that the recent trend 
 * of naming the simultaneous releases in alphabetical order, the 
 * values returned should be chronological.
 * 
 * Excludes 'callisto' and 'europa' because we don't have any
 * data captured for either of those releases. 
 *
 * @return string[]
 */
function getSimultaneousReleaseNames() {
	global $_SimultaneousReleaseDates;
	
	return array_keys($_SimultaneousReleaseDates);
	
//	global $_SimultaneousReleaseNames;
//	_loadSimultaneousReleaseNames();
//	
//	return $_SimultaneousReleaseNames;
}

function getSimultaneousReleaseDate($name) {
	global $_SimultaneousReleaseDates;
	
	return $_SimultaneousReleaseDates[$name];
}

function getCurrentSimultaneousReleaseName() {
	$names = getSimultaneousReleaseNames();
	return end($names);
}
	
function _loadSimultaneousReleaseNames() {
	global $App;
	global $_SimultaneousReleaseNames;
	if ($_SimultaneousReleaseNames) return;
	
	$names = array('ganymede', 'galileo');
	$list = "'" . implode("','", $names) . "'";
	$sql = "SELECT distinct SubKey 
		FROM 
			ProjectInfo as i 
			join ProjectInfoValues as v on (i.ProjectInfoID = v.ProjectInfoID)
		WHERE MainKey='simultaneousrelease' and SubKey not in ($list) 
		ORDER By SubKey";
	$result = $App->eclipse_sql($sql);
	
	while($row = mysql_fetch_assoc($result)) {
		$names[] = $row['SubKey'];
	}
	
	$trace = trace("Find the names of the simultaneous releases.");
	foreach($names as $name) {
		$trace->trace($name);
	}
	
	$_SimultaneousReleaseNames = $names;
}

?>