<?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 - initial API and implementation
 *******************************************************************************/

require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/common.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/debug.php");
trace_file_info(__FILE__);

require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");		
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/nav.class.php"); 	
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/menu.class.php"); 	
$App = new App();	
$Nav = new Nav();	
$Menu = new Menu();

login_committer();

include($App->getProjectCommon()); 

require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/CQ.class.php");

$smallIconDir = "http://dev.eclipse.org/small_icons";

$projectid = $App->getHttpParameter('id');
if (!is_valid_project_name($projectid)) {
	$projectid = null;
}

$bundles = $App->getHttpParameter('bundles');
$bundles = htmlentities($bundles);
$split = preg_split('/\\s/', $bundles);

$eclipse_bundles = array();
$project_bundles = array();
$non_project_bundles = array();
$other_bundles = array();

foreach($split as $bundle) {
	$bundle = htmlentities(trim($bundle));
	if (!$bundle) continue;
	
	$name = end(explode('/', $bundle));
	if (preg_match("/^org\\.eclipse\\./", $name)) {
		// TODO There are some bundles that do not match the naming scheme.
		$eclipse_bundles[] = $name;
	} else if ($cq = find_cq_for_bundle($name, $projectid)) {
		$project_bundles[$name] = $cq;
	} else if ($cqs = find_cqs_for_bundle($bundle)) {
		$non_project_bundles[$name] = $cqs;
	} else {
		$other_bundles[] = $name;
	}
}

/*
 * At this point, all the bundle names should be safe to output having
 * been processed through htmlentities. Additionally, the provided
 * projectid should also be safe as we have validated that it 
 * conforms to the standard form.
 */

$bundles = array_merge($eclipse_bundles, array_keys($project_bundles), array_keys($non_project_bundles), $other_bundles);

ob_start();

$pageKeywords = "";
$pageTitle = $projectid ? "Bundle/CQ Report for $projectid" : "Bundle/CQ Scanner";
$pageAuthor = "Wayne Beaton";
?>

<div id="midcolumn">
<div class="homeitem">
<h1><?= $pageTitle ?></h1>

<p>This tool will compare the contents of your project's downloads
against the information provided in the contribution questionnaires (CQs)
that your project has submitted. The success of this tool is limited by
the information that we have available. We know, for example, the file
patterns for many JAR'd bundles corresponding to CQs; we do not know
them all (though we are filling in the gaps regularly). This tool
should give you some sense for how accurate your automated IP Logs
are and help you to highlight problem areas.</p>

<p>Enter the id of your project, and paste the file names of the bundles that you'd like to check.
The bundles may contain path information.</p>

<p>Consider pasting a listing of the 'plugins' directory from your update site, or the
output from <code>zipinfo -1 [downloadable.zip]</code> (that's a 'one') for your project's download.</p>

<form method="post">
	<?php if (isset($_GET['trace'])) echo "<input type=\"hidden\" name=\"trace\">"; ?>
	<table border="0">
	<tr><td valign="top">Project&nbsp;id:</td><td><input name="id" type="text" width="25" value="<?php echo $projectid; ?>"/></td></tr>
	<tr><td valign="top">Bundles:</td><td><textarea rows="10" cols="75" name="bundles"><?php echo implode("\n", $bundles); ?></textarea></td></tr>
	<tr><td colspan="2"><input type="submit"/></td></tr>
	</table>
</form>

<h3>Eclipse Bundles</h3>

<p>Here we list the bundles created and owned by Eclipse projects.</p>
	
<?php 

if (!$eclipse_bundles) {
	echo "<p>There is nothing to report.</p>";
} else {
	
	echo "<ul>";
	foreach($eclipse_bundles as $bundle) {
		echo "<li>$bundle</li>";
	}
	echo "</ul>";
}
?>

<h3>Third-Party Bundles with CQs</h3>
		
<p>We have CQs in our system for these bundles for your project. Any CQs that are
<strike>crossed out</strike> are not approved (a future version of this script
will categorize these CQs separately).</p>

<?php 

if (!$project_bundles) {
	echo "<p>There is nothing to report.</p>";
} else {
	echo "<ul>";
	foreach($project_bundles as $bundle => $cq) {
		$link = $cq->as_html();
		if (!$cq->is_approved()) {
			$link = "<strike>$link</strike>";
		}
		$project = $cq->project;
		echo "<li>$bundle $link ($project)</li>";
	}
	echo "</ul>";
}
?>

<h3>Third-Party Bundles without CQs</h3>

<p>We have CQs in our system for these bundles, but we don't have an active CQ
for your project. Perhaps these bundles have been inherited from an Eclipse project that
you're packaging with your distribution. Or, maybe you need to create a piggyback
CQ for your project. Remember that version numbers are significant (i.e. you need to
have a CQ for the specific version of the third-party library you're distributing).</p>

<?php 
if (!$non_project_bundles) {
	echo "<p>There is nothing to report.</p>";
} else {
	echo "<ul>";
	foreach($non_project_bundles as $bundle => $cqs) {
		echo "<li><strong>$bundle</strong> might be from one of:<ul>";
		foreach ($cqs as $cq) {
			$link = $cq->as_html();
			if (!$cq->is_approved()) {
				$link = "<strike>$link</strike>";
			}
			echo "<li>$link ($cq->project)</li>";
		}
		echo "</ul></li>";
	}
	echo "</ul>";
}
?>

<h3>Other Bundles</h3>

<p>We're not sure what's going on with these bundles.</p>

<?php 
if (!$other_bundles) {
	echo "<p>There is nothing to report.</p>";
} else {
	echo "<ul>";
	foreach($other_bundles as $bundle) {
		echo "<li>$bundle</li>";
	}
	echo "</ul>";
}
?>

<?php echo get_trace_html(); ?>

</div>
</div>


<?php 

$html = ob_get_contents();
ob_end_clean();
$App->generatePage($theme, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html);
?>