<?php
/*******************************************************************************
 * Copyright (c) 2010, 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
 *    Wayne Beaton (Eclipse Foundation) - Added getProjectId() function
 *******************************************************************************/

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

require_once(dirname(__FILE__) . "/common.php");
require_once(dirname(__FILE__) . "/debug.php");
trace_file_info(__FILE__);

class Proposal {
	var $info;
	var $date;
	var $statuses = array();
	
	function __construct($info) {
		$this->info = $info;
	}
	
	function getName() {
		return $this->info['ProposalName'];
	}
	
	/**
	 * Once the project is created, the ProjectId field should be filled in.
	 */
	function getProjectId() {
		return $this->info['ProjectId'];
	}
	
	function getProjectUrl() {
		return normalizeHttpUrl($this->info['ProjectURL']);
	}
	
	function asHtml() {
		$name = $this->getName();
		$proposalUrl = $this->getProposalUrl();
		$projectUrl = $this->getProjectUrl();
		
		$text = htmlentities($name);
		if ($projectUrl) $text = "<a href=\"$projectUrl\">$text</a>";
		
		if ($proposalUrl) 
			$text .= " <a href=\"$proposalUrl\"><img style=\"vertical-align:top\" title=\"Review Documentation\" src=\"http://dev.eclipse.org/small_icons/mimetypes/text-x-generic.png\"/></a>";

		if ($this->isSuccessful()) {
			$text .= "<img style=\"vertical-align:top\" title=\"This project has been created.\" src=\"/projects/images/ok.gif\">";
		} else if ($this->isActive()) {
			$text .= "<img style=\"vertical-align:top\" title=\"This proposal is active.\" src=\"http://dev.eclipse.org/small_icons/status/weather-clear.png\">";
		} else {
			$text .= "<img style=\"vertical-align:top\" title=\"This proposal is inactive.\" src=\"http://dev.eclipse.org/small_icons/status/weather-showers-scattered.png\">";
		}
			
		if ($this->isWithdrawn()) $text = "<strike>$text</strike><img style=\"vertical-align:top\" title=\"Review Withdrawn\" src=\"http://dev.eclipse.org/small_icons/actions/process-stop.png\">";
		
		return $text;
	}
	
	/**
	 * This function gets the scope for the receiver from the
	 * proposal document. This is a relatively expensive operation, and
	 * no caching is provided. We use some very crude parsing to extract
	 * the contents from the <h2>Scope</h2> section of the document.
	 */
	function getScope() {
		$id = $this->getProjectId();
		$trace = trace("Finding scope for $id");
		$url = $this->getProposalUrl();
		if (!$url) {
			$trace->trace("Proposal URL is not specified.");
			return null;	
		}
		$trace->trace("URL is specified as $url");
		
		$path = $this->getProposalDocumentFilePath($url);
		
		$trace->trace("Proposal URL $path");
		
		$contents = @file_get_contents($path);
		return $this->extractScope($trace, $contents);
	}
	
	/**
	 * Find the real path of the proposal document.
	 * @internal
	 * @return NULL|string
	 */
	function getProposalDocumentFilePath($url) {		
		$path = realpath(normalizeFilePathUrl($url));
		if (is_file($path)) return $path;
		
		$file = "$path/proposal.html";
		if (is_file($file)) return $file;
		
		$file = "$path/index.php";
		if (is_file($file)) return $file;
		
		trace("Cannot find Proposal document at $url.");
		return null;
	}
	
	/**
	 * @internal
	 * @param unknown_type $url
	 * @param unknown_type $contents
	 * @return NULL|string
	 */
	function extractScope($trace, $contents) {
		if (!$contents) {	
			$trace->trace("Proposal document is empty.");
			return null;
		}
		
		if (preg_match('/<h2[^>]*>.*?Scope.*?<\/h2>(.*?)<h\d[^>]*>/is', $contents, $matches)) {
			$scope = $matches[1];
		} else {
			$trace->trace("Cannot find scope tag.");
			return null;
		}
		
		$scope = preg_replace('/<!--.*?-->/s','', $scope);
		$scope = preg_replace('/\s+/', ' ', $scope);
		$scope = trim($scope);
		
		$trace->trace("Scope: $scope");
		
		return $scope;
	}
	
	function isWithdrawn() {
		return $this->getProposalWithdrawn() != null;
	}
	
	function isSuccessful() {
		return $this->getReviewSuccessful() != null;
	}
	
	function isActive() {
		if ($this->isSuccessful()) return false;
		if ($this->isWithdrawn()) return false;
		return $this->getActiveDate() > strtotime('-3 month');
	}
	
	function getReviewSuccessful() {
		return $this->getStatus('Review Successful');
	}
	
	function getProposalWithdrawn() {
		return $this->getStatus('Proposal Withdrawn');
	}
	
	function getProposalPosted() {
		return $this->getStatus('Proposal Posted');
	}

	function getProposalUrl() {
		return normalizeHttpUrl($this->info['ProposalURL']);
	}
	/**
	 * This function returns the date of the proposal. We consider this to
	 * be the date of the earliest status. 
	 */
	function getDate() {
		if (!$this->date) $this->date = $this->compute_date();
		return $this->date;
	}
	
	function getActiveDate() {
		$date = 0;
		foreach($this->statuses as $status) {
			$status_date = $status->getDate();
			if ($status_date > $date) $date = $status_date;
		}
		return $date;		
	}
	
	/**
	 * It would be easier to just determine
	 * this value from the 'Proposal Posted' date, but we have found some
	 * entries that do not have this status...
	 * 
	 * THIS IS NOT API
	 */
	/* private */ function compute_date() {		
		$date = strtotime('now');
		foreach($this->statuses as $status) {
			$status_date = $status->getDate();
			if ($status_date < $date) $date = $status_date;
		}
		return $date;
	}
	
	/**
	 * THIS IS NOT API
	 */
	/* private */ function getStatus($text) {
		foreach($this->statuses as $status) {
			if ($status->getText() == $text) return $status;
		}
		return null;
	}
}

class ProposalStatus {
	var $info;
	
	function __construct($info) {
		$this->info = $info;
	}
	
	function getText() {
		return $this->info['Status'];
	}

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

function get_proposals($App) {
	$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
			length(trim(ProposalName)) > 0
		ORDER BY Date desc";
	
	$result = $App->foundation_sql($sql);
	
	$proposals = array();
	while($row = mysql_fetch_assoc($result)) {
		$id = $row['Id'];
		if (isset($proposals[$id])) {
			$proposal = $proposals[$id];
		} else {
			$proposal = new Proposal($row);
			$proposals[$id] = $proposal;
		}
		$proposal->statuses[] = new ProposalStatus($row);
	}
	
	return $proposals;
}


/**
 * This function returns the proposal corresponding to the project
 * with the provided id.
 * 
 * Requires that the $App variable be defined.
 * 
 * @param string $id A project id.
 */
function getProposalForProject($id) {
	if (!isValidProjectId($id)) return;
	
	global $App;
	
	$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
			trim(r.ProposalURL) != ''
			AND r.ProjectId = '$id'
		ORDER BY Date desc";

	$result = $App->foundation_sql($sql);
	$proposal = null;
	while($row = mysql_fetch_assoc($result)) {
		if (!$proposal) $proposal = new Proposal($row);
		$proposal->statuses[] = new ProposalStatus($row);
	}

	return $proposal;
}

?>