<?php
/*******************************************************************************
 * Copyright (c) 2010 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__) . '/debug.php');

$proposal_statuses=array(
	"Proposal Posted",
	"Proposal Updated 1",
	"Proposal Updated 2",
	"Proposal Updated 3",
	"Proposal Updated 4",
	"Proposal Updated 5",
	"Proposal Updated 6",
	"Proposal Updated 7",
	"Proposal Withdrawn"
);

$review_statuses=array(
	"IP Log Posted",
	"Legal Review Requested",
	"Project Archived",
	"Provisioning Complete",
	"Review Pending",
	"Review Scheduled",
	"Review Successful",
	"Review Unsuccessful",
	"Review Withdrawn",
	"Slides Posted",
	"Waiting Provisioning"
);

class Activity {
	var $data;

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

	function getDate() {
		$raw = $this->data['Date'];
		return strtotime($raw);
	}

	function getBugNumber() {
		if (!isset($this->data['BugNumber'])) return null;
		return $this->data['BugNumber'];
	}
	
	function getLink() {
		return $this->encodeUrl($this->getRawLink());
	}

	function getStatus() {
		return $this->getRawStatus();
	}

	function getRawStatus() {
		return $this->data['Status'];
	}
	
	function getProjectId() {
		return $this->data['ProjectId'];
	}
	
	function getSlidesUrl() {
		if (!isset($this->data['SlidesURL'])) return null;
		return $this->encodeUrl($this->data['SlidesURL']);
	}
	
	function getProjectUrl() {
		if (!isset($this->data['ProjectURL'])) return null;
		return $this->encodeUrl($this->data['ProjectURL']);
	}

	function getIPLogUrl() {
		if (!isset($this->data['IPLogURL'])) return null;
		return $this->encodeUrl($this->data['IPLogURL']);
	}
	
	function isWithdrawn() {
		return in_array($this->data['Status'], array('Proposal Withdrawn', 'Review Withdrawn'));
	}

	/*
	 * This function generates a Globally-unique Id (GUID) for this
	 * news item. To keep with the "globally unique" theme, I'm using
	 * the URL for this page as a base. To keep it unique within that
	 * scope, I'm appending the id of the item from our database and the
	 * status. The URL generated by this method is not intended to be
	 * meaningful; i.e. using it will not bring you to this specific
	 * item. In the RSS output, we set 'isPermaLink' to false to reflect this.
	 */
	function getGuid() {
		$id = $this->data['Id'];
		// Get the status from the parent. Receiver's impl may change the value.
		$status = str_replace(' ', '', $this->getRawStatus());
		return "http://www.eclipse.org/projects/reviews-rss.php?$id.$status";
	}
	
	/* private */ function encodeUrl($url) {
		if (!$url) return $url;
//		if( strpos($url, "http:") === false )
//			$url = "http://www.eclipse.org" . $url;
//	
//		return urlencode($url);
		return $url;
	}
}

class Review extends Activity {
	function getName() {	
		// If the project name isn't specified for a review, then
		// we've likely gone through a creation review. Make sure that
		// the title reflects this.
		return $this->data['ProjectName'] ? $this->data['ProjectName'] : $this->data['ProposalName'];
	}
	
	function getTitle() {
		$projectName = $this->getName();
		$reviewName = $this->getReviewName();
		$status = $this->getStatus();

		return "$projectName $reviewName $status";
	}

	function getDescription() {
		return $this->getReviewName();
	}
	
	function getReviewName() {
		return $this->data['ReviewName'] ? $this->data['ReviewName'] : "Creation";
	}
	
	/**
	 * This method answers the date that the review either occurred or will occur
	 * on. The date is returned as a UNIX date (i.e. not a string).
	 */
	function getReviewDate() {
		return strtotime($this->data['ReviewDate']);
	}
	
	function isUnsuccessful() {
		return in_array($this->data['Status'], array ('Review Withdrawn', 'Review Unsuccessful'));
	}
	
	function isSuccessful() {
		return in_array($this->data['Status'], array ("Project Archived", "Provisioning Complete", "Review Successful", "Waiting Provisioning"));
	}
	
	function toHtmlString() {
		global $App;
		
		$name = htmlentities($this->getName());
		$description = htmlentities($this->getDescription()) . ' Review';
		
		$projectUrl = $this->getProjectUrl();
		if ($projectUrl) $name = "<a href=\"$projectUrl\">$name</a>";
		
		$slidesUrl = $this->getSlidesUrl();
		$iplogUrl = $this->getIPLogUrl();
		
		$date = $this->getReviewDate();
		if ($date) {
			$date = $App->getFormattedDate($date, 'short');
		} else {
			$date = "Not scheduled";
		}
		$date = str_replace(' ', '&nbsp;', $date);
		
		$icons = '';
		if ($slidesUrl) 
			$icons .= "<a href=\"$slidesUrl\"><img style=\"vertical-align:top\" title=\"Review Documentation\" src=\"http://dev.eclipse.org/small_icons/mimetypes/x-office-presentation.png\"/></a>";
		
		if ($iplogUrl) {
			$icons .= "<a href=\"$iplogUrl\"><img style=\"vertical-align:top\" title=\"IP Log\" src=\"http://dev.eclipse.org/small_icons/status/dialog-information.png\"/></a>";
		}
		
		$status = $this->getStatus();
		
		if ($this->isSuccessful()) {
			$icons .= "<img style=\"vertical-align:top\" title=\"$status\" src=\"/projects/images/ok.gif\">";
		}
				
		if ($this->isUnsuccessful()) {
			$date = "<strike>$date</strike>";
			$name = "<strike>$name</strike>";
			$description = "<strike>$description</strike>";
			$icons .= "<img style=\"vertical-align:top\" title=\"$status\" src=\"http://dev.eclipse.org/small_icons/actions/process-stop.png\">";
		}
	
		return "$name $description $icons $date";
	}
	
	/**
	 * Return an appropriate link for the receiver. If the receiver
	 * represents a the date that the IP Log was posted and the IPLogURL
	 * value has been set, return that value. Then, if the SlidesURL has
	 * been set, return that. Otherwise, return the ProjectURL.
	 *
	 */
	function getRawLink() {
		if (strcmp("IP Log Posted", $this->getStatus()) == 0) return $this->data['IPLogURL'];
		if ($this->data['SlidesURL']) return $this->data['SlidesURL'];		
		return $this->data['ProjectURL'];
	}
}

class Proposal extends Activity {
	function getName() {
		return $this->data['ProposalName'];
	}
	
	function getTitle() {
		$proposalName = $this->getName();
		$status = $this->getStatus();

		return "$proposalName $status";
	}

	function getDescription() {
		return "Project Proposal";
	}
	
	function getStatus() {
		/*
		 * There are a number of statuses that are of the form
		 * 'Proposal Updated n'; here, we remove the n.
		 */
		$status = parent::getStatus();
		if (strpos($status, "Proposal Updated") === 0) return "Proposal Updated";
		return $status;
	}

	function isUnsuccessful() {
		return in_array($this->data['Status'], array ('Proposal Withdrawn'));
	}
	
	/**
	 * A proposal is never successful. If it's successful, then it would have been turned into
	 * a review.
	 */
	function isSuccessful() {
		return false;
	}
	
	function getRawLink() {
		return $this->data['ProposalURL'];
	}
}

/**
 * This function obtains the recent project proposal and
 * review activity.
 *
 * @param $age How many days back in time do we go?
 * @param $limit Limit the number of rows returned (-1 means all rows).
 * @param $includeHistory Do we include all changes on the project (true), or only the most recent activity (false).
 * @return void
 */
function getRecentActivity($age, $limit=-1, $includeHistory=false) {		
	global $App;
	
	if ($App->devmode) {
		return array(
			new Review(array('ProjectName' => 'A really long review name', 'Date' => 'today', 'Status' => 'A status that causes some wrapping')),
			new Review(array('ProjectName' => 'A Proposal of some merit', 'Date' => '-2 days', 'Status' => 'Proposal Posted'))
		);
	
	}
	
	return getActivity(generateRecentActivitySql($age, $limit, $includeHistory));
}

function getAllCompleteReviewActivity($limit = -1) {
	$sql = "
		SELECT 
			r.id as Id, 
			r.ProjectName, r.ProjectId, 
			ProjectURL, ProposalURL, SlidesURL, IPLogURL, BugNumber, ReviewDate,
			ReviewName, ProposalName, 
			s.status as Status, s.value as Date 
		FROM 
			ProjectReviews as r 
			join ProjectReviewStatus as s on (r.id = s.id and s.value != 0)
		WHERE
			Status in ('Review Successful', 'Review Unsuccessful', 'Review Withdrawn')
			and ReviewDate != 0
		order by ReviewDate desc";
	
	if ($limit > 0) {
		$sql .= " limit $limit";
	}
	
	return getActivity($sql);
}

/*private*/ function generateRecentActivitySql($age, $limit, $includeHistory) {
	$sql = "
		SELECT 
			r.id as Id, 
			r.ProjectName, r.ProjectId, 
			ProjectURL, ProposalURL, SlidesURL, IPLogURL, BugNumber,
			ReviewName, ProposalName, 
			s.status as Status, s.value as Date 
		FROM 
			ProjectReviews as r 
			join ProjectReviewStatus as s on (r.id = s.id and date(s.value) > subdate(now(), interval $age day))";
	
	if (!$includeHistory) {
		$sql .= " join (select ID, Max(value) as v from ProjectReviewStatus group by id) as m on (m.Id = r.id and m.v = s.value)";
	}
	
	$sql .= " order by date desc";
	
	if ($limit > 0) {
		$sql .= " limit $limit";
	}
	
	return $sql;
}

function getUpcomingReviews() {	
	global $App;
	
	$start = findPreviousThursday();
	$end = findNextWednesday();
	$sql = "
		SELECT 
			r.id as Id, 
			r.ProjectName, r.ProjectId, 
			ProjectURL, ProposalURL, SlidesURL, IPLogURL, BugNumber,
			ReviewName, ProposalName, 
			s.status as Status,
			date(r.ReviewDate) as Date
		FROM 
			ProjectReviews as r 
			join ProjectReviewStatus as s on (r.id = s.id)
			join (select ID, Max(value) as v from ProjectReviewStatus group by id) as m on (m.Id = r.id and m.v = s.value)
		WHERE
			r.ReviewDate > subdate(now(), interval 1 week)
		ORDER By date(ReviewDate) between '$start' and '$end' desc, date(ReviewDate), ProjectId";
	
	$activity = getActivity($sql);

	unset($activity['2850']);
	unset($activity['2852']);
	
	if ($upcoming = json_decode(@file_get_contents('http://projects.eclipse.org/json/reviews/upcoming'), true)) {
		foreach($upcoming as $row) {
			$id = $row['Id'];
			$status = $row['Status'];
			$activity[$id] = new Review($row);
		}
	}

	if ($upcoming = json_decode(@file_get_contents('http://polarsys.org/json/reviews/upcoming'), true)) {
		foreach($upcoming as $row) {
			$id = $row['Id'];
			$status = $row['Status'];
			$activity[$id] = new Review($row);
		}
	}
	
	usort($activity, 'sortUpcomingReviews');
	
	return $activity;
}

/**
 * Compare two Reviews for sorting. The most recently completed
 * reviews are sorted first, followed by everything else. Within
 * the groups, everything is sorted by date and then by project id.
 * 
 * @internal
 * @param Review $a
 * @param Review $b
 * @return -1, 0, 1 if <,==,>
 */
function sortUpcomingReviews($a, $b) {
	$now = strtotime('now');
	$lastWeek = strtotime('-1 week');
	
	$aDate = $a->getDate();
	$bDate = $b->getDate();
	
	$aRecent = ($aDate < $now) && ($aDate > $lastWeek);
	$bRecent = ($bDate < $now) && ($bDate > $lastWeek);
	
	if ($aRecent == $bRecent) {
		if ($aDate < $bDate) return -1;
		if ($aDate > $bDate) return 1;
		
		return strcasecmp($a->getProjectId(),$b->getProjectId());
	}
	
	if ($aRecent == 1) return -1;
	return 1;
}

function findPreviousThursday($start = 'now') {
// 	$date = new DateTime($start);
// 	$diff = $date->format('w') - 4; // 4 == Thursday
// 	if ($diff < 0) $diff += 7;
// 	$thursday = $date->sub(new DateInterval('P' . $diff . 'D'));
	
// 	return $thursday->format('Y-m-d');

	$date = strtotime($start);
	$diff = date('w', $date) - 4; // 4 == Thursday
	if ($diff < 0) $diff += 7;
	$thursday = $date - ($diff * 24 * 60 * 60);
	
	return date('Y-m-d', $thursday);
}

function findNextWednesday($start = 'now') {
// 	$date = new DateTime($start);
// 	$diff = 3 - $date->format('w'); // 3 == Wednesday
// 	if ($diff < 0) $diff += 7;
// 	$wednesday = $date->add(new DateInterval('P' . $diff . 'D'));

// 	return $wednesday->format('Y-m-d');

	$date = strtotime($start);
	$diff = 3 - date('w', $date); // 3 == Wednesday
	if ($diff < 0) $diff += 7;
	$wednesday = $date + ($diff * 24 * 60 * 60);
	
	return date('Y-m-d', $wednesday);
}
/**
 * This function returns a collection of Proposal-type activities
 * reaching the specified number of months (default 6) into the past.
 * 
 * @param int $age How many months in the past do we go back?
 * @return Array of Proposals
 */
function getNewProjectProposals($age = 6) {
	global $App;
	
	if ($App->devmode) {
		return array(
			new Proposal(array('ProposalName' => 'Proposal One', 'Status' => 'Proposal Posted', 'Date' => '-10 Days', 'ProposalURL' => '/proposalOne')),
			new Proposal(array('ProposalName' => 'Proposal Two', 'Status' => 'Proposal Updated 1', 'Date' => '-32 Days', 'ProposalURL' => '/proposalTwo')),
			new Proposal(array('ProposalName' => 'Proposal Three', 'Status' => 'Proposal Updated 1', 'Date' => '-4 Months', 'ProposalURL' => '/proposalThree')),
			new Proposal(array('ProposalName' => 'Proposal Four', 'Status' => 'Proposal Withdrawn', 'Date' => '-5 Months', 'ProposalURL' => '/proposalFour'))
		);
	}
	
	return getActivity(generateNewProjectProposalsSql($age));
}

/* private */ function generateNewProjectProposalsSql($age) {
	global $proposal_statuses;

	$status = "'" . implode("','", $proposal_statuses) . "'";
	$sql = "
		SELECT 
			r.id as Id, 
			r.ProjectName, r.ProjectId, 
			ProjectURL, ProposalURL, SlidesURL, IPLogURL, BugNumber
			ReviewName, ProposalName, 
			s.status as Status,
			s.value as Date
		FROM 
			ProjectReviews as r 
			join ProjectReviewStatus as s on (r.id = s.id)
			join (select ID, Max(value) as v from ProjectReviewStatus group by id) as m on (m.Id = r.id and m.v = s.value)
		WHERE
			Status in ($status)
			and s.value > subdate(now(), interval $age month)
		ORDER By Date desc";
	
	return $sql;
}

/**
 * This function does the actual work of executing the SQL and 
 * extracting the result. The query string passed to this method
 * must request a minimum of two columns from the database: 'Id' 
 * and 'Status'. More realistically, a lot more columns than that
 * are required to make the results useful.
 * 
 * @see #getUpcomingReviews()
 */
/*private*/ function getActivity($sql) {
	global $App;
	global $review_statuses;
	global $proposal_statuses;
	
	$result = $App->foundation_sql($sql);

	$activity = array();
	while($row = mysql_fetch_assoc($result)) {
		$id = $row['Id'];
		$status = $row['Status'];
		if (in_array($status, $review_statuses)) $activity[$id] = new Review($row);
		else if (in_array($status, $proposal_statuses)) $activity[$id] = new Proposal($row);
	}
	
	return $activity;
}


?>