<?php
$ignoredWorkingSets = array('EXCLUDE', 'STEM-Data-EarthScience');

$workingSetRepoMap = array(
	'STEM-Features' => 'org.eclipse.stem.git',
	'STEM-Docs' => 'org.eclipse.stem.git',
	'STEM-ThirdPartyLibs' => 'org.eclipse.stem.git',
	'STEM-Core' => 'org.eclipse.stem.git',
	'STEM-Analysis' => 'org.eclipse.stem.git',
	'STEM-DiseaseModels' => 'org.eclipse.stem.git',
	'STEM-PopulationModels' => 'org.eclipse.stem.git',
	'STEM-FoodProductionModels' => 'org.eclipse.stem.git',
	'STEM-ModelGen' => 'org.eclipse.stem.git',
	'STEM-Distributed' => 'org.eclipse.stem.git',
	'STEM-Tests' => 'org.eclipse.stem.git',
	'STEM-Data-EarthScience' => 'org.eclipse.stem.data.earthscience.git',
	'STEM-Data' => 'org.eclipse.stem.data.git',
	'STEM-Releng' => 'org.eclipse.stem.git',
);

define('DATA_BUILD_MAP_PATH', 'releng/org.eclipse.stem.releng/maps/stem.data.map');
define('BUILD_MAP_PATH', 'releng/org.eclipse.stem.releng/maps/stem.map');
define('BUILD_MAP_DIRECTORY_PATH', 'releng/org.eclipse.stem.releng/maps/directories.properties');

define('WORKING_SET_MATCH', '!WS:');
define('MAP_ENTRY_REGEX', '(.*)@(.*)=(.*)');
define('MAP_ENTRY_PATH_PREFIX', "\${checkoutDir}");

define('PROTOCOL_GIT', 'git://');
define('PROTOCOL_HTTP', 'http://');
define('PROTOCOL_HTTPS', 'https://');
define('PROTOCOL_SSH', 'ssh://');


//define('REPOSITORY_ROOT_SSH', 'ssh://git.eclipse.org/gitroot/stem/');
define('REPOSITORY_ROOT', 'git.eclipse.org:29418/stem/');
define('REPOSITORY_ROOT_HTTPS', 'git.eclipse.org/r/stem/');
define('REPOSITORY_ROOT_ANON', 'git.eclipse.org/gitroot/stem/');

//http://git.eclipse.org/c/stem/org.eclipse.stem.git/plain/releng/org.eclipse.stem.releng/maps/directories.properties

define('GIT_ROOT_HTTP', 'http://git.eclipse.org/c/stem/org.eclipse.stem.git/plain/');

define('PROVIDER_ID', 'org.eclipse.egit.core.GitProvider');
define('PROVIDER_ENTRY_TEMPLATE', '1.0,$REPO$,$BRANCH$,$PATH$');

define('RELENG_WS_ENTRY', '!WS:STEM-Releng');
define('RELENG_PROJECT_ENTRY', 'resource@org.eclipse.stem.releng=COPY,${source.path.releng},org.eclipse.stem.releng');
define('TARGETPLATFORM_PROJECT_ENTRY', 'resource@org.eclipse.stem.releng.targetplatforms=COPY,${source.path.releng},org.eclipse.stem.releng.targetplatforms');

define('DEFAULT_BRANCH', 'master');


$workingSetEntryTemplates = array();
$workingSetEntryTemplates['default'] = array('factoryID'=>'org.eclipse.ui.internal.model.ResourceFactory','path'=>'$NAME$','type'=>'4');
$workingSetEntryTemplates['plugin'] = array('factoryID'=>'org.eclipse.jdt.ui.PersistableJavaElementFactory', 'elementID'=>'=$NAME$');
$workingSetEntryTemplates['fragment'] = $workingSetEntryTemplates['plugin'];

//<project reference="1.0,ssh://hcsvn.almaden.ibm.com/gitroot/stem/org.eclipse.stem.git,master,analysis/org.eclipse.stem.analysis"/>

function getUsernamePrefix()
{
	if (isset($_REQUEST['u'])) {
		$username = $_REQUEST['u'];
		if ($username) {
			return $username .'@';
		}
	}
	return "";
}

function getRepositoryForWorkingSet($wsName)
{
	global $workingSetRepoMap;
	$repoRoot = getRepositoryRoot(false);
	$repoName = $workingSetRepoMap[$wsName];
	
	return $repoRoot . $repoName;
	
}

function getBuildDirectoryMapUrl()
{
	$repositoryRoot = getGitHttpRoot();
	return $repositoryRoot .'/'. BUILD_MAP_DIRECTORY_PATH;
	//return "/Users/mattadav/projects/STEM/workspaces/svn/releng/org.eclipse.stem.releng/maps/directories.properties";
}

function getRequestedBranch()
{
	return DEFAULT_BRANCH;
}

function getBuildDirectoryMap()
{
	$directoryMapData = @file(getBuildDirectoryMapUrl());
	if (!$directoryMapData) {
		return false;
	}
	
	$repositoryRoot = getRepositoryRoot();
	
	$data = array();
	foreach ($directoryMapData as $line) {
		$tokens = explode("=", $line);
		if (is_array($tokens) && sizeof($tokens) == 2) {
		
			$name = $tokens[0];
			$path = $tokens[1];

			if ($name == "source.path") {
				$path = "";//$repositoryRoot;
				$data[$name] = trim($path);
			} else {
				if (@eregi('^\$\{(.*)\}\/(.*)$', $path, $t2)) {
					$parent = $t2[1];
					if (isset($data[$parent]) && $data[$parent] != "") {
						$path =  $data[$parent] ."/" .$t2[2];
					} else {
						$path =  $t2[2];
					}
					$data[$name] = trim($path);
				} else {
					$data[$name] = "";
				}
			}
		
			
		}
	}
	
	//echo "<pre>";
	//print_r($data);
	//echo "</pre>";
	
	return $data;
	
}

function getGitHttpRoot()
{
	return GIT_ROOT_HTTP;
}

function getBuildMapUrl() 
{
	$repositoryRoot = getGitHttpRoot();
	return $repositoryRoot .'/'. BUILD_MAP_PATH;
}

function getDataBuildMapUrl() 
{
	$repositoryRoot = getGitHttpRoot();
	return $repositoryRoot .'/'. DATA_BUILD_MAP_PATH;
}

function getRepositoryRoot($forceHttp = false)
{
	if (!$forceHttp && isset($_REQUEST['r']) && $_REQUEST['r'] == "ssh") {
		$protocol = PROTOCOL_SSH;
		$repository_root = REPOSITORY_ROOT;
	} else if (!$forceHttp && isset($_REQUEST['r']) && $_REQUEST['r'] == "https") {
		$protocol = PROTOCOL_HTTPS;
		$repository_root = REPOSITORY_ROOT_HTTPS;
	}  else {
		$protocol = PROTOCOL_GIT;
		$repository_root = REPOSITORY_ROOT_ANON;
	}
	
	$path = $protocol . getUsernamePrefix() . $repository_root;
	
	return $path;
}

function processMapEntry($line, $dirMap)
{
	$repositoryRoot = getRepositoryRoot();
	
	$data = array();
	$data['line'] = $line;
	
	//feature@org.eclipse.stem.feature=COPY,${checkoutDir}/features,org.eclipse.stem.feature
	if (@eregi(MAP_ENTRY_REGEX, $line, $tokens)) {
		
	
		//COPY,${checkoutDir}/features,org.	eclipse.stem.feature
		$pathTokens = explode(",", $tokens[3]);
		if ($pathTokens[0] == "COPY") {
		
			$dirKey = trim($pathTokens[1]);
			$dirKey = substr($dirKey, 2, $dirKey-1);
			
			if (!array_key_exists($dirKey, $dirMap)) {
				return false;
			}
			
			$path = $dirMap[$dirKey];
		
			// Local entry
			
			if ($path != "") {
				$data['path'] = $path . '/' . $pathTokens[2];
			} else {
				$data['path'] = $pathTokens[2];
			}
			$data['pathRelative'] = $pathTokens[2];
			//$data['path'] = str_replace(MAP_ENTRY_PATH_PREFIX, $repositoryRoot, $pathTokens[1]) ."/". $tokens[2];
		}
		
		$data['type'] = $tokens[1];
		$data['name'] = $tokens[2];
	}
	
	//echo "<pre>";
	//print_r($data);
	//echo "</pre>";
	
	return $data;
}

function processMapFile($lines)
{
	$data = array();
	
	$buildDirMap = getBuildDirectoryMap();
	$currentWorkingSet = "EXCLUDE";
	
	//echo "<pre>";
	//print_r($buildDirMap);
	//echo "</pre>";
	
	foreach ($lines as $line) {
		$line = trim($line);
		if ($line != "") {
			if ($line{0} == "!" || $line{0} == "#") {
				// comment line
				$lineMatch = strstr($line, WORKING_SET_MATCH);
				// Matched a working set string
				if ($lineMatch !== FALSE) {
					$currentWorkingSet = str_replace(WORKING_SET_MATCH, "", $lineMatch);
				}				
			} else {
				if ($currentWorkingSet === false) {
					continue;
				}
				
				
				$entry = processMapEntry($line, $buildDirMap);
				if (!$entry) {
					continue;
				}
				$data[$currentWorkingSet][] = $entry;
			}
		}		
	}

	return $data;
}


function buildProviderDOM($xml, $workingSets)
{
	global $ignoredWorkingSets, $workingSetRepoMap;

	
	$xml = createElementDOM($xml, "provider");
	createAttributeDOM($xml, "id", PROVIDER_ID);
	
	foreach ($workingSets as $workingSetName => $workingSetEntries) {
		if (!isExcludedWorkingSet($workingSetName)) {
			// Not an ignored working set.  Process.
			
			$repo = getRepositoryForWorkingSet($workingSetName);
			foreach ($workingSetEntries as $workingSetEntry) {
				$projectRef = createElementDOM($xml,"project");

						if (!isset($workingSetEntry['path'])) {
							continue;
						}
				
				//<project reference="1.0,ssh://hcsvn.almaden.ibm.com/gitroot/stem/org.eclipse.stem.git,master,analysis/org.eclipse.stem.analysis"/>

				$entryString = PROVIDER_ENTRY_TEMPLATE;
				$entryString = str_replace("\$PATH\$", $workingSetEntry['path'], $entryString);
				$entryString = str_replace("\$NAME\$", $workingSetEntry['name'], $entryString);
				$entryString = str_replace("\$BRANCH\$", getRequestedBranch(), $entryString);
				$entryString = str_replace("\$REPO\$", $repo , $entryString);

				//DEFAULT_BRANCH
				createAttributeDOM($projectRef, "reference", $entryString);
			}
		}
	}
}

function isExcludedWorkingSet($wsName)
{
	global $ignoredWorkingSets;
	$ws = false;
	if (isset($_REQUEST['ws'])) {
		return !($_REQUEST['ws'] == $wsName);
	}
	
	return in_array($wsName, $ignoredWorkingSets);
}




/**
<workingSets editPageId="org.eclipse.jdt.ui.JavaWorkingSetPage" id="1310766141425_10" label="STEM-Tests" name="STEM-Tests">
<item elementID="=org.eclipse.stem.tests.automaticexperiment" factoryID="org.eclipse.jdt.ui.PersistableJavaElementFactory"/>
<item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/org.eclipse.stem.core.feature" type="4"/>
</workingSets>
 */
function addWorkingSetEntryDOM($wsXML, $workingSetEntry)
{
	if (!isset($workingSetEntry['path'])) {
		return;
	}


	global $workingSetEntryTemplates;

	$itemXML = createElementDOM($wsXML, "item");

	if (array_key_exists($workingSetEntry['type'],$workingSetEntryTemplates)) {
		$attributes = $workingSetEntryTemplates[$workingSetEntry['type']];
	} else {
		$attributes = $workingSetEntryTemplates['default'];
	}

	foreach ($attributes as $attributeName => $attributeValue) {	
		$attributeValue = str_replace("\$PATH\$", $workingSetEntry['path'], $attributeValue);
		$attributeValue = str_replace("\$NAME\$", $workingSetEntry['name'], $attributeValue);
		createAttributeDOM($itemXML, $attributeName, $attributeValue);
	}
}

function buildWorkingSetDOM($rootXML, $workingSets)
{
	global $ignoredWorkingSets;

	$seq = 0;

	foreach ($workingSets as $workingSetName => $workingSetEntries) {
		if (!isExcludedWorkingSet($workingSetName)) {
			$wsXML = createElementDOM($rootXML, "workingSets");
			createAttributeDOM($wsXML, "editPageId", "org.eclipse.jdt.ui.JavaWorkingSetPage");
			createAttributeDOM($wsXML, "id", time() ."_". $seq++);
			createAttributeDOM($wsXML, "label", $workingSetName);
			createAttributeDOM($wsXML, "name", $workingSetName);
				
			foreach ($workingSetEntries as $workingSetEntry) {
				addWorkingSetEntryDOM($wsXML, $workingSetEntry);
			}
		}
	}
}

function buildProjectSetDOM($data)
{
	$doc = new DOMDocument('1.0');
	$doc->formatOutput = true;
	
	
	$root = createElementDOM($doc, "psf");
	createAttributeDOM($root, "version", "2.0");

	
	buildProviderDOM($root, $data);
	buildWorkingSetDOM($root, $data);
	return $doc;
}

function createElementDOM($root, $name)
{
	if ($root->ownerDocument != NULL) {
		$element = $root->ownerDocument->createElement($name);
	} else {
		$element = $root->createElement($name);
	}
	
	$root->appendChild($element);
	
	return $element;
}

function createAttributeDOM($root, $name, $value)
{
	$attr = $root->ownerDocument->createAttribute($name);
	$attr->value = $value;
	$root->appendChild($attr);
}


function addRelengProjects($buildMapData)
{
	$buildMapData[] = RELENG_WS_ENTRY;
	$buildMapData[] = RELENG_PROJECT_ENTRY;
	$buildMapData[] = TARGETPLATFORM_PROJECT_ENTRY;
	
	return $buildMapData;
}


function getBuildMap()
{
	$dataBuildMap = @file(getDataBuildMapUrl());
	$coreBuildMap = @file(getBuildMapUrl());
	
	$buildMapData = array_merge($coreBuildMap, $dataBuildMap);
	if (!$buildMapData) {
		return false;
	}
	
	
	//$buildMapData = @file(getBuildMapUrl());
	
	$buildMapData = addRelengProjects($buildMapData);
	return $buildMapData;
}


$buildMapData = getBuildMap();
if (!$buildMapData) {
	echo "Error:  Cannot get project set data.  Check that the branch or tag exists.  Only branches from STEM 1.2.1 and newer are compatible.";
	exit();
}


$data = processMapFile($buildMapData);
$xml = buildProjectSetDOM($data);

Header("Content-type: text/xml");
echo $xml->saveXML();
exit();






/**


function buildWorkingSetXML($rootXML, $workingSets) 
{
	global $ignoredWorkingSets;
	
	$seq = 0;
	
	foreach ($workingSets as $workingSetName => $workingSetEntries) {
		if (!in_array($workingSetName, $ignoredWorkingSets)) {
			$wsXML = $rootXML->addChild("workingSets");
			$wsXML->addAttribute("editPageId", "org.eclipse.jdt.ui.JavaWorkingSetPage");
			$wsXML->addAttribute("id", time() ."_". $seq++);
			$wsXML->addAttribute("label", $workingSetName);
			$wsXML->addAttribute("name", $workingSetName);
			
			foreach ($workingSetEntries as $workingSetEntry) {
				addWorkingSetEntry($wsXML, $workingSetEntry);
			}		
		}
	}
}

function buildProjectSetXML($data)
{	
	$root = new SimpleXMLElement("<psf/>");
	$root->addAttribute("version", "2.0");
	buildProviderXML($root, $data);
	buildWorkingSetXML($root, $data);
	return $root;	
}

function buildProviderXML($xml, $workingSets)
{
	
	
	$xml = $xml->addChild("provider");
	$xml->addAttribute("id", PROVIDER_ID);
	
	foreach ($workingSets as $workingSetName => $workingSetEntries) {
		if (!in_array($workingSetName, $ignoredWorkingSets)) {
			// Not an ignored working set.  Process.
			
			foreach ($workingSetEntries as $workingSetEntry) {
				$projectRef = $xml->addChild("project");
				
				$entryString = PROVIDER_ENTRY_TEMPLATE;
				$entryString = str_replace("\$PATH\$", $workingSetEntry['path'], $entryString);
				$entryString = str_replace("\$NAME\$", $workingSetEntry['name'], $entryString);
				
				$projectRef->addAttribute("reference", $entryString);	
			}
		}
	}
}

function addWorkingSetEntry($wsXML, $workingSetEntry)
{
	global $workingSetEntryTemplates;
	
	$itemRef = $wsXML->addChild("item");
	
	if (array_key_exists($workingSetEntry['type'],$workingSetEntryTemplates)) {
		$attributes = $workingSetEntryTemplates[$workingSetEntry['type']];
	} else {
		$attributes = $workingSetEntryTemplates['default'];
	}
	
	foreach ($attributes as $attributeName => $attributeValue) {	
		$attributeValue = str_replace("\$PATH\$", $workingSetEntry['path'], $attributeValue);
		$attributeValue = str_replace("\$NAME\$", $workingSetEntry['name'], $attributeValue);
		$itemRef->addAttribute($attributeName, $attributeValue);
	}
}


 */
?>