<?php 
/*******************************************************************************
 * Copyright (c) 2009 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
 *******************************************************************************/

/*
 * This file assumes that the $App variable has been defined.
 */

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

class CQ {
	var $id;
	var $project;
	var $description;
	var $state;
	var $status;
	var $resolution;
	var $keywords;
	var $attachments;
	var $bundles = array();
	var $parent;
	var $piggyback_cqs = array();
	
	function CQ($id, $description, $keywords=array(), $attachments=0) {
		$this->id = $id;
		$this->description = $description;
		$this->keywords = $keywords;
		$this->attachments = $attachments;
	}
	
	public function is_root() {
		return !$this->parent;	
	}
	
	public function &get_root($recursion_list = array()) {
		if (in_array($this, $recursion_list)) throw new RecursiveAncestryException();
		if ($this->parent == $this) return $this;
		if (!$this->parent) return $this;
		
		$recursion_list[] = $this;
		$parent = $this->parent;
		$root = &$parent->get_root($recursion_list);
		
		return $root;
	}
	
	/**
	 * PROVISIONAL
	 * Enter description here ...
	 */
	public function get_related() {
		$related = array();
		$this->get_root()->gather_related($related);
		return $related;
	}
	
	/**
	 * This method finds a related CQ for the project with the provided id.
	 * That is, the receiver and all of it's descendent piggybacks are 
	 * searched to find one that is owned by the given project id.
	 * 
	 * @param $projectid The id of the project to search for.
	 * @return An instance of CQ or <code>null</code>.
	 */
	public function find_cq_for_project($projectid, $check_parents=false, $check_children=false) {
		trace("Checking CQ $this->id for $projectid");
		if ($this->project == $projectid) {
			trace("Found CQ $this->id for $projectid");
			return $this;
		}
		foreach ($this->piggyback_cqs as $piggyback) {
			trace("Looking for piggyback");
			$match = $piggyback->find_cq_for_project($projectid);
			if ($match) {
				trace("Match found in piggyback CQ $match->id");
				return $match;
			}
		}
		if ($check_parents) {
			$parent = get_project_parent_id($projectid);
			if ($parent) {
				trace("Checking parent, $parent, for CQ");
				if ($parent) {
					$match = $this->find_cq_for_project(get_project_parent_id($projectid), true, false);
					if ($match) return $match;
				}
			}
		}
		if ($check_children) {
			trace("Checking subprojects.");
			$match = $this->find_cq_for_subproject($projectid);
			if ($match) return $match;
		}
		
		return null;
	}
	
	/* private */ function find_cq_for_subproject($projectid) {
		if (is_valid_subproject_id($projectid, $this->project)) {
			return $this;
		}
		foreach ($this->piggyback_cqs as $piggyback) {
			$match = $piggyback->find_cq_for_subproject($projectid);
			if ($match) return $match;
		}
		return null;
	}
	
	/* private */ function gather_related(&$related) {
		$related[$this->id] = $this;
		foreach ($this->piggyback_cqs as $piggyback) {
			$piggyback->gather_related($related);
		}
	}
	
	public function as_html() {
		return "<a href=\"https://dev.eclipse.org/ipzilla/show_bug.cgi?id=$this->id\">CQ $this->id</a>";
	}
	
	public function is_contribution() {
		return $this->has_keyword('epl');
	}
	
	public function is_third_party() {
		return $this->has_keyword("nonepl");
	}
	
	public function has_keyword($needle) {
		foreach ($this->keywords as $keyword) {
			if ($keyword == $needle) return true;
		}	
		return false;
	}
	
	public function is_resolved() { 
		if (!$this->status) return false;
		return in_array($this->status, array('RESOLVED', 'VERIFIED', 'CLOSED'));
	}
	
	public function is_approved() {
		if (!$this->is_resolved()) return false;
		return $this->state == 'approved';
	}
	
	public function is_invalid() {
		if (!$this->is_resolved()) return false;
		if (!$this->resolution) return false;
		return in_array($this->resolution, array('INVALID', 'WONTFIX', 'DUPLICATE', 'WORKSFORME', 'MOVED'));	
	}
	
	public function add_bundle($bundle, $regex) {
		$this->bundles[$bundle] = $regex;	
	}
	
	public function get_parent_id() {		
		preg_match('/ATO[ ]*CQ[ ]*([0-9]*)/', $this->description, $matches);
		if (count($matches) > 1) return $matches[1];
		
		$matches = null;
		preg_match('/PB[ ]*CQ[ ]*([0-9]*)/', $this->description, $matches);
		if (count($matches) > 1) return $matches[1];
		
		$matches = null;
		preg_match('/PB[ ]*([0-9]*)/', $this->description, $matches);
		if (count($matches) > 1) return $matches[1];
		
		$matches = null;
		preg_match('/Orbit CQ[ ]*([0-9]*)/', $this->description, $matches);
		if (count($matches) > 1) return $matches[1];
		
//		$matches = null;
//		preg_match('/CQ[ ]*#?([0-9]*)/', $this->description, $matches);
//		if (count($matches) > 1) return $matches[1];
		
		return null;
	}
}

define("CQ_SHOW_NONE", 0);
define("CQ_SHOW_ANCESTORS", 1);
define("CQ_SHOW_PIGGYBACKS", 2);
define("CQ_SHOW_BUNDLES", 4);
define("CQ_SHOW_KEYWORDS", 8);
define("CQ_SHOW_ALL", CQ_SHOW_ANCESTORS + CQ_SHOW_PIGGYBACKS + CQ_SHOW_BUNDLES + CQ_SHOW_KEYWORDS);

function to_node($doc, $root, $cq, $options = CQ_SHOW_ALL, $tag = 'cq', $recursion_list=array()) {
	$cq_element = $doc->createElement($tag);
	$cq_element->setAttribute('id', $cq->id);
	$cq_element->setAttribute('project', $cq->project);
	$cq_element->setAttribute('status', $cq->status);
	$cq_element->setAttribute('state', $cq->state);
	$cq_element->setAttribute('resolution', $cq->resolution);
	$cq_element->setAttribute('description', $cq->description);
	$cq_element->setAttribute('attachments', $cq->attachments);
	$cq_element->setAttribute('third-party', $cq->is_third_party() ? "true" : "false");
	$cq_node = $root->appendChild($cq_element);
	
	if ($options & CQ_SHOW_KEYWORDS) {
		foreach ($cq->keywords as $keyword) {
			$keyword_element = $doc->createElement('keyword');
			$keyword_element->setAttribute('name', $keyword);
			$cq_node->appendChild($keyword_element);
		}
	}
	
	if ($options & CQ_SHOW_BUNDLES) {
		foreach ($cq->bundles as $bundle => $regex) {
			$bundle_element = $doc->createElement('bundle');
			$bundle_element->setAttribute('id', $bundle);
			$bundle_element->setAttribute('regex', $regex);
			$cq_node->appendChild($bundle_element);
		}
	}
	
	if ($options & CQ_SHOW_PIGGYBACKS) {
		foreach($cq->piggyback_cqs as $piggyback) {
			to_node($doc, $cq_node, $piggyback, CQ_SHOW_NONE, 'piggyback');
		}
	}
	
	if ($options & CQ_SHOW_ANCESTORS) {
		// If this is the second time that we've encountered the receiver
		// in the recursion, bail out to avoid an infinite loop.
		if (in_array($cq, $recursion_list)) {
			$parent_element = $doc->createElement('recursive-parent');
			$cq_node->appendChild($parent_element);
			return;
		} 
	
		// If there's a parent, then we're going to recurse. If not, just bail.
		if (!$cq->parent) return;
		
		$recursion_list[] = $cq;
		to_node($doc, $cq_node, $cq->parent, CQ_SHOW_ANCESTORS, 'parent-cq', $recursion_list);
	}
}

class RecursiveAncestryException extends Exception {}

function find_root_cqs() {
	$cqs = array();
	foreach(find_cqs() as $cq) {
		if ($cq->is_root()) $cqs[] = $cq;
	}
	return $cqs;
}

/**
 * This function finds a single CQ. Note that multiple calls to this
 * function will return the same object.
 * 
 * @param $id int id of the the CQ to find.
 */
function find_cq($id) {
	$cqs = find_cqs();
	return $cqs[$id];	
}

/**
 * This function, curiously enough, finds the known CQs. The computation
 * is done exactly once. Multiple calls to this function will return the
 * same array.
 * 
 * If this function is called on the server, it finds the CQs from the database.
 * If it is called in "Development Mode", it makes a RESTful webservice call
 * to the server to get the CQ data.
 * 
 */
function find_cqs() {
	// TODO Consider implementing a completely offline mode.
	global $App;
	global $_cqs;
	
	if (!isset($_cqs)) $_cqs = $App->devmode ? load_cqs_from_server() : primitive_find_cqs();
	
	return $_cqs;
}

/**
 * This function returns the CQ assigned to the project with the provided id
 * that contributes the bundle with the provided name.
 */
function &find_cq_for_bundle($bundle, $projectid, $check_parents=false, $check_children=false) {
	trace("Find CQ for bundle $bundle in project $projectid.");
	foreach (find_root_cqs() as $cq) {
		foreach($cq->bundles as $pattern => $regex) {
			trace("Comparing $regex from CQ $cq->id to $bundle...");		
			if (@preg_match($regex, $bundle)) {
				trace("Found a bundle match for $bundle in CQ $cq->id");
				$match = $cq->find_cq_for_project($projectid, $check_parents, $check_children);
				if ($match) {					
					trace("Found a project match for $projectid in CQ $cq->id");
					return $match;
				}
			}
		}
	}
	$match = null;
	return $match;
}

function find_cqs_for_bundle($bundle) {
	$cqs = array();
	foreach (find_root_cqs() as $cq) {
		foreach($cq->bundles as $pattern => $regex) {	
			if (@preg_match($regex, $bundle)) {
				$cq->gather_related($cqs);
			}
		}
	}
	return $cqs;
}

/**
 * This function does the dirty work of actually finding the CQs from the IPZilla Database.
 * 
 * THIS IS NOT PUBLIC API.
 */
function primitive_find_cqs() {
	global $App;
	
	$sql = "
		SELECT 
			bugs.bug_id as id, 
			components.name as project,
			bugs.short_desc as description,
			bugs.bug_status as status,
			bugs.resolution as resolution,
			bugs.keywords as keywords,
			bugs.bug_severity as state,
			count(attachments.attach_id) as attachments
		FROM 
			bugs
			join components on (bugs.component_id = components.id)
			left join attachments on (bugs.bug_id = attachments.bug_id and attachments.isobsolete = 0)
		group by bugs.bug_id";
	
	$result = $App->ipzilla_sql( $sql );

	$cqs = array();

	while( $row = mysql_fetch_assoc($result) ) {
		$id = $row['id'];
		$keywords = preg_split('/, */', $row['keywords']);
		$cq = new CQ($id,$row['description'],$keywords,$row['attachments']);
		$cq->project = $row['project'];
		$cq->status = $row['status'];
		$cq->resolution = $row['resolution'];
		$cq->state = $row['state'];
		$cqs[$id] = $cq;
	}
	
	foreach ($cqs as $cq) {
		$parent_id = $cq->get_parent_id();
		if ($parent_id == $cq->id) continue;
		if ($parent_id) {
			$cq->parent = $cqs[$parent_id];
		}
	}
	
	foreach ($cqs as $cq) {
		try {
			$root = $cq->get_root();	
		} catch (RecursiveAncestryException $e) {
			continue;
		}
		if (!$root) continue;
		if ($root == $cq) continue;
		$root->piggyback_cqs[] = $cq;
	}
	
	read_bundle_mappings_file($cqs);
	
	return $cqs;
}

/**
 * This function reads the bundle mappings from the cq-map.txt file
 * and--when possible--connects the bundle name with a cq. Each line in the
 * text that matches the pattern '[cq#], [bundle name]' is assumed to
 * be a valid mapping.
 * 
 * This function returns nothing; it has the side effect of (potentially)
 * modifying the CQ instances in the first parameter.
 * 
 * THIS IS NOT PUBLIC API.
 * 
 * @param unknown_type $cqs
 */
function read_bundle_mappings_file(&$cqs) {		
	$top = trace("Reading bundle mappings.");
	
	$filepath = $_SERVER['DOCUMENT_ROOT'] . '/projects/ip-check/cq-map.txt';
	$mappings = file($filepath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
	
	foreach($mappings as $mapping) {
		$tracer = $top->trace("Processing bundle mapping '$mapping'.");
		
		$matches = null;
		preg_match('/\s*([0-9]+),\s*([\w\.-]+)/', $mapping, $matches);
		if (count($matches) > 2) {
			$id = $matches[1];
			$bundle = $matches[2];
			$tracer->trace("Found CQ/bundle mapping: CQ $id maps to $bundle");
			
			if (isset($cqs[$id])) {
				// First, we find the CQ that corresponds to the mapping
				$cq = $cqs[$id];
				try {
					// Then, we find the root CQ (sometimes the mapping is
					// between a piggyback CQ and bundle).
					$cq = $cq->get_root();
					if ($cq->id != $id) {
						$tracer->trace("CQ $id has root $cq->id");
					}
				} catch (RecursiveAncestryException $e) {
					$tracer->trace("Cannot find root for CQ $cq.");
					continue;
				}
				
				$root = $cq->get_root();
				/*
				 * The regex patterns formed below have a start delimiter (^)
				 * but no end delimiter ($) to allow for matches of files with
				 * extra junk (e.g. .jar.pack.gz) at the end. This may end up
				 * being more flexible than we need.
				 */
				$matches = null;
				preg_match('/([a-zA-Z0-9\.-_]+)[_-]((?:\d+\.){3})(.*\.)?jar/', $bundle, $matches);
				if (count($matches) > 0) {
					$pattern = $matches[1] . '_' . $matches[2];
					$regex = $matches[1] . '[_-]' . $matches[2];			
					$regex = str_replace('.', '\.', $regex);
					$regex = '/^' . $regex . '(.*\.)?jar/';
					$pattern = "$pattern*.jar";
					
					$root->add_bundle($pattern, $regex);
					$tracer->trace("Bundle '$bundle' becomes pattern '$pattern' ($regex).");
					
					$sourcePattern = $matches[1] . '.source_' . $matches[2];		
					$sourceRegex = $matches[1] . 'source[_-]' . $matches[2];									
					$sourceRegex = str_replace('.', '\.', $sourceRegex);
					$sourceRegex = '/^' . $sourceRegex . '(.*\.)?jar/';
					$sourcePattern = "$sourcePattern*.jar";					

					$root->add_bundle($sourcePattern, $sourceRegex);
					$tracer->trace("Source for bundle '$bundle' becomes pattern '$sourcePattern' ($sourceRegex).");
				} else {
					$pattern = $bundle;
					$regex = str_replace('.', '\.', $pattern);
					$regex = "/^$regex/";
									
					$tracer->trace("Bundle '$bundle' becomes pattern '$pattern' ($regex).");
					$root->add_bundle($pattern, $regex);
				}
			} else {
				$tracer->trace("CQ $id not found!");
			}
		} else {
			$tracer->trace("Skipping CQ-bundle-mapping: $mapping (incomplete information)");
		}
	}
}

/**
 * PROVISIONAL
 * @param $id
 */
function find_root_cq($id) {
	$cqs = find_cqs();
	if (!isset($cqs[$id])) return null;
	$cq = $cqs[$id];
	if (!$cq) return null;
	return $cq->get_root();
}

/**
 * PROVISIONAL
 * @param $ids
 * @param $projectid
 */
function find_related_cq($ids, $projectid) {
	foreach ($ids as $id) {
		$cq = find_root_cq($id);
		if (!$cq) continue;
		$related = $cq->find_cq_for_project($projectid);
		if ($related) return $related;
	}
	return null;
}

/**
 * Force the CQs to be loaded from the server via HTTP. Otherwise, CQs will be lazily
 * loaded from the database when they are required.
 */
function load_cqs_from_server($file = "https://www.eclipse.org/projects/xml/cqs.php") {
	global $_cqs;
	$_cqs = array();
	$raw = simplexml_load_file($file);
	
	foreach($raw->cq as $item) {
		$id = (int)$item['id'];
		$description = $item['description'];
		$description = "$description";
		
		$cq = new CQ($id, $description);
		$cq->project = $item['project'];
		$cq->status = $item['status'];
		$cq->state = $item['state'];
		
		foreach ($item->keyword as $keyword) {
			$cq->keywords[] = $keyword['name'];
		}
		
		foreach ($item->bundle as $bundle) {
			$cq->add_bundle((String)$bundle['id'], (String)$bundle['regex']);
		}
		
		$_cqs[$id] = $cq;
	}
	
	foreach($raw->cq as $item) {
		$id = (int)$item['id'];
		$cq = $_cqs[$id];
		
		foreach ($item->piggyback as $piggyback) {
			$cq->piggyback_cqs[] = $_cqs[(int)$piggyback['id']];
		}
	}
	
	//read_bundle_mappings_file($cqs);
	
	return $_cqs;
}

?>
