<?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 (Eclipse Foundation)- initial API and implementation
 *******************************************************************************/
require_once(dirname(__FILE__) . "/common.php");
require_once(dirname(__FILE__) . "/debug.php");
trace_file_info(__FILE__);

function getLoggedInCommitter() {
	global $_loggedInCommitter;
	if (isset($_loggedInCommitter)) return $_loggedInCommitter;
	$_loggedInCommitter = null;
	
	global $App;
	
	$Session = $App->useSession("optional"); 
    $friend	 = $Session->getFriend();
    
  	if (!$friend->getBugzillaID()) return null;
    if (!$friend->getIsCommitter()) return null;
    
    $committer = new Committer();
    
    $email = $friend->getEmail();
    $sql = "select 
    		p.PersonID, 
    		p.LName, 
    		p.FName, 
    		p.Email,
    		p.Comments,
    		pp.ProjectID, 
    		pp.Relation,
    		pp.ActiveDate,
    		pp.InactiveDate
    	from People as p
    		left join PeopleProjects as pp on (p.PersonID = pp.PersonID)
		where EMail = '$email'";
    $result = $App->foundation_sql($sql);
    while ($row = mysql_fetch_assoc($result)) {
    	$committer->id = $row['PersonID'];
    	if (!isset($row['ProjectID'])) continue;
    	$committer->projectRelations[] = new ProjectRelation($row);
    }
    
    $_loggedInCommitter = $committer;
    
    return $committer;
}

function getCommittersForProject($id, $preloadCommits = true) {
	mustBeValidProjectId($id);
	trace("Loading committers for $id");
	$sql = "
		select distinct
			p.PersonID, 
			p.FName,
			p.LName,
			p.Email,
			p.Comments,
			pp.ProjectID, 
			pp.Relation,
			pp.ActiveDate,
			pp.InactiveDate,
			o.OrganizationID as CompanyId,
			o.Name1 as Company
		from People as p
	    	join PeopleProjects as pp on (p.PersonID = pp.PersonID)
			left join OrganizationContacts as oc on (p.PersonId = oc.PersonId)
			left join Organizations as o on (oc.OrganizationId = o.OrganizationId)
		where 
			pp.ProjectID = '$id'";
	
	$committers = _loadCommitters($sql);
	
	return $committers;
}

function getCommitters() {
	$sql = "
		select distinct
			p.PersonID, 
			p.FName,
			p.LName,
			p.Email,
			p.Comments,
			pp.ProjectID, 
			pp.Relation,
			pp.ActiveDate,
			pp.InactiveDate,
			o.OrganizationID as CompanyId,
			o.Name1 as Company
		from People as p
	    	join PeopleProjects as pp on (p.PersonID = pp.PersonID)
			left join OrganizationContacts as oc on (p.PersonId = oc.PersonId)
			left join Organizations as o on (oc.OrganizationId = o.OrganizationId)";

	return _loadCommitters($sql);
}

/**
 * Answer an array mapping committer Id to full name (first + last) for
 * each of the provided committer Ids.
 */
function getCommitterNames($ids) {
	global $App;
	
	$committers = array();
	
	$values = implode("','", $ids);
	$result = $App->foundation_sql("select distinct PersonId, concat(FName, ' ', LName) as Name from People where PersonId in ('$values')");
	while ($row = mysql_fetch_assoc($result)) {
		$id = $row['PersonId'];
		$name = $row['Name'];
		
		$committers[$id] = $name;
	}
	return $committers;
}

/**
 * Current implementation does not guarantee uniqueness. i.e. if you
 * call this function more than once, subsequent calls will return
 * different objects.
 */
/* private */ function _loadCommitters($sql) {
	global $App;
	$committers = array();
	$result = $App->foundation_sql($sql);
	while ($row = mysql_fetch_assoc($result)) {
		$id = $row['PersonID'];
		if (!isset($committers[$id])) {
			$committer = new Committer();
			$committer->id = $id;
			$committer->firstName = $row['FName'];
			$committer->lastName = $row['LName'];
			$committer->email = $row['Email'];
			$committer->companyId = $row['CompanyId'];
			$committer->company = $row['Company'];
			$committer->comments = $row['Comments'];
			$committers[$id] = $committer;
		} else {
			$committer = $committers[$id];
		}
		
		$committer->projectRelations[] = new ProjectRelation($row);
	}
	return $committers;
}

class Committer {
	/**
	 * Committer ID from the Foundation Database.
	 * @var string
	 */
	var $id;
	
	/**
	 * First name. Duh.
	 * @var string
	 */
	var $firstName;
	
	/**
	* Last name. Duh.
	* @var string
	*/
	var $lastName;
	
	var $email;
	
	var $companyId;
	var $company;
		
	/**
	 * Array of project relations.
	 * @var ProjectRelation[]
	 */
	var $projectRelations = array();
	
	var $commits = array();
	
	var $comments;
	
	function getName() {
		return "$this->firstName $this->lastName";
	}
	
	function isCommitter($id, $when='now') {
		return $this->hasProjectRelation($id, 'CM', $when);
	}
	
	function isMentor($id, $when='now') {
		return $this->hasProjectRelation($id, 'ME', $when);
	}
	
	function isEmeritus($id, $when='now') {
		return $this->hasProjectRelation($id, 'CE', $when);
	}
	
	function isProjectLead($id, $when='now') {
		return $this->hasProjectRelation($id, 'PL', $when);
	}
	
	function isPmcMember($id, $when='now') {
		return $this->hasProjectRelation($id, 'PM', $when);
	}
	
	function isPmcLead($id, $when='now') {
		return $this->hasProjectRelation($id, 'PD', $when);
	}
	
	function hasCommits($id, $when='now') {
		return $this->getCommitSummary($id) ? true : false;
	}
	
	/**
	 * Get the commit summary for this user for a particular
	 * project from the commits index database.
	 * 
	 * @param string $id a project id, e.g. 'rt.gyrex'
	 */
	function getCommitSummary($projectId) {
		mustBeValidProjectId($projectId);
		
		if (isset($this->_commitSummary[$projectId])) return $this->_commitSummary[$projectId];
		
		global $App;
		
		$result = $App->dashboard_sql("select count, period from commits_index where login='$this->id' and project ='$projectId' order by count desc;");
		
		$this->_commitSummary[$projectId] = array();
		while($row = mysql_fetch_assoc($result)) {
			$this->_commitSummary[$projectId][$row['period']] = $row['count'];
		}
		return $this->_commitSummary[$projectId];
	}
	
	function isActive($id, $when='now') {
		if (!$summary = $this->getCommitSummary($id)) return false;
		return isset($summary['3']);
	}
	
	/**
	 * This method answers true if the committer represented by the instance
	 * has the right credentials to submit an IP Log for all of the projects
	 * specified in the parameter.
	 * 
	 * Note that this method is a little specialized, but it is useful in a couple
	 * of different contexts, so having it here sort of makes sense.
	 * 
	 * @param string[] $ids An array of project ids.
	 */
	function canSubmitIPLogForAllProjects($ids, $when='now') {
		if ($this->isCommitterOnAllProjects($ids, $when)) return true;
		if ($this->isPMCRepresentativeForAllProjects($ids, $when)) return true;
		return false;
	}	
	
	function isPMCRepresentativeForAllProjects($ids, $when='now') {		
		foreach($ids as $id) {
			if (!$this->isPMCRepresentativeForProject($id, $when)) return false;
		}
		return true;
	}
	
	function isPMCRepresentativeForProject($id, $when='now') {
		require_once dirname(__FILE__) . '/Project.class.php';
		
		$top = getProject($id)->getTopLevelProject()->getId();
		
		foreach($this->projectRelations as $relation) {
			if (!$relation->isActive($when)) continue;
			if ($top != $relation->projectId) continue;
			if ($relation->relation == 'PD') return true; // PMC Lead
			if ($relation->relation == 'PM') return true; // PMC Member
		}
		return false;
	}
	
	/**
	 * Answers true if the receiver is a committer on all of the projects
	 * in the provided list, or false otherwise.
	 * 
	 * Enter description here ...
	 * @param string[] $ids Array of project ids.
	 * @param string $date Optional date to check in string format. Default: current date
	 * @return bool
	 */
	function isCommitterOnAllProjects($ids, $when) {
		foreach($ids as $id) {
			if (!$this->isCommitterOnProject($id, $when)) return false;
		}
		return true;
	}
	
	function isCommitterOnProject($id, $when = 'now') {
		return $this->hasProjectRelation($id, 'CM', $when);
	}
	
	/* private */ function hasProjectRelation($id, $relationCode, $when = 'now') {
		foreach($this->projectRelations as $relation) {
			if (!$relation->isActive($when)) continue;
			if ($id != $relation->projectId) continue;
			if ($relation->relation == $relationCode) return true;
		} 
		return false;
	}
	
	/**
	* This function extract the email addresses from the comment and returns
	* them--along with the provided primary email address--in an array.
	*
	* This is a stop-gap solution for the need to represent multiple email addresses
	* for some users in some contexts. Alternative email addresses are represented in
	* the comment field in the form 'alt-email:somebody@someplace.com'. Multiple
	* alternative addresses can be provided. The tag can occur anywhere in the comment
	* and--while it is not always required--it is good practice to leave a space
	* between multiple entries.
	*
	* WTB Bug 355885
	*/
	function getAltEmails() {
		preg_match_all('/alt-email:([A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4})/i', $this->comments, $matches);
		$emails = array();
		foreach($matches[1] as $email) {
			$emails[] = $email;
		}
		return $emails;
	}
	
	function hasEmailAddress($address) {
		if (strcasecmp($this->email, $address) == 0) return true;
		foreach($this->getAltEmails() as $email) {
			if (strcasecmp($email, $address) == 0) return true;
		}
		return false;
	}
	
	function getOrganization() {
		if (!$this->companyId) return null;
		require_once(dirname(__FILE__)) . '/Organization.class.php';
		return getOrganization($this->companyId);
	}
	
	function getAllAddresses() {
		global $App;
		$sql = "select 
				AddressId, 
				Address1, Address2, Address3,
				City, ProvStateRegion,PostalCode, CCode
			from PeopleAddresses
			where PersonID='$this->id'
			order by AddressId";
		$addresses = array();
		$result = $App->foundation_sql($sql);
		while ($row = mysql_fetch_assoc($result)) {
			$addresses[] = $row;
		}
		return $addresses;
	}
}

class ProjectRelation {
	var $projectId;
	var $relation;
	var $activeDate;
	var $inactiveDate;
	
	function __construct($row) {
		$this->projectId = $row['ProjectID'];
		$this->relation = $row['Relation'];
		$this->activeDate = $row['ActiveDate'] ? strtotime($row['ActiveDate']) : null;
		$this->inactiveDate = $row['InactiveDate'] ? strtotime($row['InactiveDate']) : null;
	}
	
	function isActive($when = 'now') {
		if (!$this->activeDate) return false;
		
		$date = strtotime($when);
		if ($date < $this->activeDate) return false;
		
		if (!$this->inactiveDate) return true;
		if ($date > $this->inactiveDate) return false;
		
		return true;
	}
}
?>