<?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;

	$activity = array();
	
	$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";
	
	foreach(getActivity($sql) as $review) {
	    $key = $review->getName() . $review->getReviewName();
	    $activity[$key] = $review;
	}
	
	$forges = array(
	    'http://projects.eclipse.org/json/reviews/upcoming',
	    'http://polarsys.org/json/reviews/upcoming',
	    'http://locationtech.org/json/reviews/upcoming'
	);
		
	foreach($forges as $forge) {
    	if ($upcoming = json_decode(@file_get_contents($forge), true)) {
    		foreach($upcoming as $row) {
    		    $review = new Review($row);
    		    $key = $review->getName() . $review->getReviewName();
    			$activity[$key] = $review;
    		}
    	}
	}
	
	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 sortByActivityDate($a, $b) {
    $aDate = $a->getDate();
    $bDate = $b->getDate();

    if ($aDate < $bDate) return 1;
    if ($aDate > $bDate) return -1;
    return 0;
}

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;

	$activity = getActivity(generateNewProjectProposalsSql($age));
	
	$sources = array(
	    'http://projects.eclipse.org/json/proposals',
	    'http://www.polarsys.org/json/proposals',
	    'http://www.locationtech.org/json/proposals'
	);

	foreach($sources as $source) {
    	if ($forge = json_decode(@file_get_contents($source), true)) {
    	    foreach($forge as $row) {
    	        $id = $row['Id'];
    	        $activity[$id] = new Proposal($row);
    	    }
    	}
	}
	
// 	if ($forge = json_decode(@file_get_contents('http://locationtech.org/json/proposals'), true)) {
// 	    foreach($forge as $row) {
// 	        $id = $row['Id'];
// 	        $activity[$id] = new Proposal($row);
// 	    }
// 	}
	
	usort($activity, 'sortByActivityDate');
	
	return $activity;
}

/* 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 = (int)$row['Id'];
		
        if ($id == 2850) continue;
		if ($id == 2852) continue;
		
		$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;
}


?>