<?php

define('MYBB_DUPS', 104);
define('MYBB_DUPLINES', 2973);

if(file_exists('data.php')) {
	require 'data.php';
}
if(!isset($data)) $data = array();

$plugins = array();
foreach(glob('*') as $fn)
	if(is_dir($fn) && $fn != 'mybb') $plugins[] = $fn;

foreach($plugins as $p) {
	if(!isset($data[$p])) $data[$p] = array();
	$metrics =& $data[$p];
	
	if(isset($metrics['ncloc'])) continue;
	
	echo "Doing $p...\n";
	exec('phploc --log-xml '.$p.'-loc.xml '.$p.' >NUL');
	exec('phpcpd --log-pmd '.$p.'-cpd.xml '.$p.' >NUL');
	exec('phpcpd --log-pmd '.$p.'-cpdm.xml '.$p.' mybb >NUL');
	
	// read XMLs
	$loc = xml_parse_data(file_get_contents($p.'-loc.xml'));
	foreach($loc[0]['children'] as $tag) {
		$tagname = strtolower($tag['tag']);
		switch($tagname) {
			case 'directories':
			case 'files':
			case 'cloc':
			case 'ncloc':
			case 'nclocClasses':
			case 'ccn':
			case 'classes':
			case 'functions':
			case 'methods':
			case 'constants':
				$metrics[$tagname] = intval($tag['value']);
				break;
		}
	}
	unset($loc);
	// for some reason, phploc doesn't show files+directories if there's only one
	if(!$metrics['files']) $metrics['files'] = 1;
	
	$cpd = read_cpd($p.'-cpd.xml');
	$metrics['dupsnum'] = $cpd[0];
	$metrics['dupsloc'] = $cpd[1];
	
	$cpd = read_cpd($p.'-cpdm.xml');
	$metrics['dupsmnum'] = $cpd[0]-MYBB_DUPS;
	$metrics['dupsmloc'] = $cpd[1]-MYBB_DUPLINES;
	
	unlink($p.'-loc.xml');
	unlink($p.'-cpd.xml');
	unlink($p.'-cpdm.xml');
	
	// other stuff: total bytes, js/css stats?
	$metrics['codebytes'] = get_php_size($p);
	
	// write output
	// not necessary now
}

file_put_contents('data.php', '<?php $data = '.var_export($data, true).';');


function get_php_size($d) {
	$sum=0;
	foreach(glob($d.'/*') as $f) {
		if(is_dir($f))
			$sum += get_php_size($f);
		elseif(strtolower(substr($f, -4)) == '.php')
			$sum += filesize($f);
	}
	return $sum;
}

function &read_cpd($fn) {
	$ret = array(0, 0); // dups, lines
	$xml = xml_parse_data(file_get_contents($fn));
	if($xml[0]['children']) foreach($xml[0]['children'] as $tag) {
		if($tag['tag'] != 'DUPLICATION') continue;
		++$ret[0];
		$ret[1] += $tag['attributes']['LINES'];
	}
	return $ret;
}


function &xml_parse_data($data) {
	$xp = xml_parser_create();
	xml_parser_set_option($xp, XML_OPTION_SKIP_WHITE, true);
	$dummy_add = (substr(trim($data), 0, 2) != '<?');
	$data = str_replace('&', '&amp;', $data); // work around for PHP's crappy parser
	if($dummy_add)
		$data = '<dummy>'.$data.'</dummy>';
	xml_parse_into_struct($xp, $data, $vals);
	xml_parser_free($xp);
	// make nested array
	$ret = array();
	$astack = array(&$ret);
	
	foreach($vals as &$tag) {
		if($tag['type'] == 'close') {
			array_pop($astack);
			continue;
		}
		$tag['children'] = array();
		
		// fix up the mess we made with our PHP entity workaround
		if(isset($tag['value']))
			$tag['value'] = html_entity_decode(str_replace('&nbsp;', ' ', $tag['value']));
		if(!empty($tag['attributes'])) {
			foreach($tag['attributes'] as $k => &$v)
				$v = html_entity_decode(str_replace('&nbsp;', ' ', $v));
		}
		
		$add2 =& $astack[count($astack)-1];
		$add2[] = $tag;
		if($tag['type'] == 'open') {
			$astack[] =& $add2[count($add2)-1]['children'];
		}
	}
	if($dummy_add)
		return $ret[0]['children'];
	else
		return $ret;
}
