<?php
/*******************************************************************************
 * Copyright (c) 2010 The Eclipse Foundation.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
require_once(dirname(__FILE__) . "/Forge.class.inc");
require_once(dirname(__FILE__) . "/common.php");
require_once(dirname(__FILE__) . "/debug.php");

class Proposal {
	var $info;
	var $date;
	var $statuses = array();

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

	public static function getAllProposals() {
	    /*
	     * Visit each of the forges to pull out their proposals. Note that the
	     * service that generates this data was designed to output it in the
	     * same sort of format that we'd expect from the database query
	     * result.
	     */
	    foreach(Forge::getForges() as $forge) {
	        $all = json_decode(getUrlContents("{$forge->getUrl()}/json/proposals/all"), true);
	        foreach($all as $row) {
	            $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;
	}

	public static function getActiveProposals() {
	    $proposals = array();

	    // We only care about proposals in the default forge.
	    $forge = Forge::getDefault();
        $url = "{$forge->getUrl()}/json/proposals";
        $json = getUrlContents($url);
        if ($list = json_decode($json, true)) {
            foreach($list as $row) {
                $proposals[] = new Proposal($row);
            }
	    }

	    usort($proposals, 'proposals_sortByDate');

	    return $proposals;
	}

	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=\"Proposal\" 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\">";
		}

		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.
	 *
	 * @deprecated
	 */
	function getScope() {
		return null;
	}

	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 true;
	}

	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']);
	}
}

/**
 * @deprecated use Proposal::getAllProposals()
 * @return Proposal[]
 */
function get_proposals() {
    return Proposal::getAllProposals();}


/**
 * This function returns the proposal corresponding to the project
 * with the provided id.
 *
 * @deprecated
 * @param string $id A project id.
 */
function getProposalForProject($id) {
	return null;
}

/**
 * @deprecated use Proposal::getActiveProposals()
 * @return Proposal[]
 */
function getProposals() {
    return Proposal::getActiveProposals();
}


function proposals_sortByDate($a, $b) {
	$aDate = $a->getDate();
	$bDate = $b->getDate();

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

?>