<?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.git',
    'STEM-Data' => 'org.eclipse.stem.git',
	'STEM-Releng' => 'org.eclipse.stem.git',
);

define('DATA_BUILD_MAP_PATH', 'org.eclipse.stem/releng/org.eclipse.stem.releng/maps/stem.data.map');
define('BUILD_MAP_PATH', 'org.eclipse.stem/releng/org.eclipse.stem.releng/maps/stem.map');
define('BUILD_MAP_DIRECTORY_PATH', 'org.eclipse.stem/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);
	}
}


 */
?>