<?php
/*******************************************************************************
 * Copyright (c) 2011, 2016 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
 *******************************************************************************/
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();

$pageTitle 		= "Eclipse Project Status";
$pageAuthor		= "Wayne Beaton";
$pageKeywords	= "eclipse,scm,vcs,dvcs,git,cvs,svn";

require_once $_SERVER['DOCUMENT_ROOT'] . '/projects/classes/Project.class.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/projects/classes/images.inc';
require_once $_SERVER['DOCUMENT_ROOT'] . '/projects/classes/common.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/projects/classes/debug.php';

//mustBeCommitter();

$columnDefinitions = array(
        'name' => array(
                'label' => 'Project'
        ),
        'id' => array(
                'label' => 'Project',
                'function' => function($value, $key, $project) {
                    $link = $project['url'];
                    return "<a href=\"$link\">$value</a>";
                }
        ),
        'top' => array('label' => 'Top-Level'),
        'phase' => array(
                'label' => 'Phase',
               'function' =>
                    function($value, $key, $project) {
                        global $images;
                        return $value == 'incubating' ? "<img src=\"$images->incubation_conforming_small\"/>" : '&nbsp;';
                    }
        ),
        'liveliness' => array(
                'label' => 'Liveliness',
                'function' =>
                    function($value, $key, $project) {
                        $liveliness = getLivelinessIcon($value);
                        return "<img src=\"$liveliness\"/>";
                    }
        ),
        'committers' => array('label' => 'Committers Count'),
        'organizations' => array('label' => 'Orgs Count'),
        'initial_cq' => array(
                'label' => 'Initial Contribution',
                'function' =>
                function($value, $key, $project) {
                    if (!isset($value)) return "&nbsp;";
                    return "<a href=\"$value\"><img src=\"/projects/images/external.gif\"/></a>";
                }
        ),
        'initial_cq_created' => array('label' => 'Initial Contribution Created'),
        'initial_cq_pmc' => array('label' => 'Initial Contribution PMC Approved'),
        'initial_cq_checkin' => array('label' => 'Initial Contribution Check-in'),
        'initial_cq_approved' => array('label' => 'Initial Contribution Approved'),
        'initial_cq_latency' => array(
                'label' => 'Time Since IC Change',
                'function' =>
                    function($value, $key, $project) {
                        if (@$project['initial_cq_approved']) return '--';
                        if ($checkin = @$project['initial_cq_checkin'])
                            return getTimeSince($checkin);
                        if ($created = @$project['initial_cq_created'])
                            return getTimeSince($created);
                        return '--';
                },
                'sort' =>
                    function($value, $key, $project) {
                        if (@$project['initial_cq_approved']) return 0;
                        if ($checkin = @$project['initial_cq_checkin'])
                            return (int)(time() - strtotime($checkin));
                        if ($created = @$project['initial_cq_created'])
                            return (int)(time() - strtotime($created));
                        return 0;
                    },
                'class' => 'column-align-right'

        ),
        'commits_initial' => array('label' => 'Initial Commit'),
        'commits_latest' => array('label' => 'Latest Commit'),
        'commits' => array(
                'label' => 'Commits Count',
                'function' =>
                    function($value, $key, $project) {
                        if ($value !== null)
                            return number_format($value);
                        return '--';
                    },
                'sort' =>
                    function($value, $key, $project) {
                        return (int)$value;
                    },
                'class' => 'column-align-right'
        ),
        'commits_latency' => array(
                'label' => 'Time Since Last Commit',
                'function' =>
                    function($value, $key, $project) {
                        if ($latest = @$project['commits_latest'])
                            return getTimeSince($latest);
                        return '--';
                    },
                'sort' =>
                    function($value, $key, $project) {
                        if ($latest = @$project['commits_latest'])
                            return (int)(time() - strtotime($latest));
                        return 0;
                    },
                'class' => 'column-align-right'
        ),
        'downloads_first' => array(
                'label' => 'Oldest Download',
        ),
    );

function getColumnDefinitions() {
    global $columnDefinitions;
    return $columnDefinitions;
}

function getColumnDefinition($key) {
    global $columnDefinitions;
    return $columnDefinitions[$key];
}

function getTimeSince($date) {
    if (!$date) return 0;
    $milliseconds = date(time() - strtotime($date));
    $days = number_format(ceil($milliseconds / (60 * 60 * 24)));
    return "$days days";
}

function filter($info) {
	foreach($_GET as $key=>$value) {
		if (isset($info[$key])) {
			if ($info[$key] != $value) return true;
		}
	}
	return false;
}

function getProjectStatus() {
    global $App;

	$projects = array();

	foreach(getActiveProjects() as $project) {
		switch ($id = $project->getId()) {
			case 'polarsys' :
				break;
			default:
				$info = array(
				    'project' => $project,
					'id' => $id,
					'name' => $project->getName(),
					'top' => $project->getTopLevelProject()->getId(),
					'topName' => preg_replace('/ Root$/','', $project->getTopLevelProject()->getName()),
					'phase' => $project->isInIncubationPhase() ? 'incubating' : 'regular',
					'url' => $project->getUrl(),
					'liveliness' => $project->getLiveliness()
				);

				if (!filter($info)) $projects[$id] = $info;
		}
	}

	addDashData($projects);
	addInitialContributionStats($projects);

	return $projects;
}

/**
 * Add stats that are tracked by Dash. This generally refers to values
 * that are calculated in batch and cached on the dashboard database.
 *
 * @param mixed $projects
 */
function addDashData(&$projects) {
    global $App;
    $sql = "
        select distinct
            p.subproject as id,
            date(ps.initialCommit) as commits_initial,
            date(ps.latestCommit) as commits_latest,
            ps.totalCommits as commits,
            count(distinct pca.company) as organizations,
            count(distinct pda.login) as committers,
            min(pd.first) as downloads_first
        from ProjectRollup as p
            left join ProjectCompanyActivity as pca on p.subproject=pca.project
            left join ProjectCommitterActivity as pda on p.subproject=pda.project
            left join ProjectStats as ps on p.subproject=ps.project
            left join ProjectInfoDownloads as pd on p.subproject=pd.project
        group by p.subproject";
    $result = $App->dashboard_sql($sql);

    while ($row = mysql_fetch_assoc($result)) {
        $id = $row['id'];
        if (isset($projects[$id])) {
            $projects[$id] += $row;
        }
    }
}

/**
 * Add information about the initial contribution to the
 * project data. Note that data is only provided for projects
 * that are already represented in the array.
 *
 * @param mixed $projects
 */
function addInitialContributionStats(&$projects) {
    global $App;

    $sql = "select
        	f.name as id,
            b.bug_id as cq,
            b.short_desc as title,
        	date(b.creation_ts) as created,
        	max(date(pmc.bug_when)) as pmc,
        	max(date(checkin.bug_when)) as checkin,
        	max(date(approved.bug_when)) as approved
        from bugs as b
        	join (select
        			c.name,
        			min(bb.bug_id) as cq
        		from bugs as bb
        		    join products as p on bb.product_id = p.id
        		    join components as c on bb.component_id = c.id
        			join keywords as k on bb.bug_id=k.bug_id
        			join keyworddefs as kd on k.keywordid=kd.id and kd.name in ('projectcode')
        		where c.name not in ('foundation-internal', 'IP_Discussion', 'IP', 'dsdp')
                    and bug_severity not in ('withdrawn')
                    and resolution not in ('INVALID')
        		group by c.id) as f on b.bug_id=f.cq
        	left join bugs_activity as pmc on b.bug_id=pmc.bug_id and pmc.added in ('PMC_Approved+')
        	left join bugs_activity as checkin on b.bug_id=checkin.bug_id and checkin.added in ('checkin', 'checkintocvs')
        	left join bugs_activity as approved on b.bug_id=approved.bug_id and approved.added in ('approved', 'approved_all_projects', 'FIXED', 'WORKSFORME')
        group by f.name
        order by f.name";

	$result = $App->ipzilla_sql($sql);

	while ($row = mysql_fetch_assoc($result)) {
	    $id = $row['id'];
	    if (!isset($projects[$id])) continue;
	    $cq = $row['cq'];
	    $projects[$id]['initial_cq'] = "https://dev.eclipse.org/ipzilla/show_bug.cgi?id=$cq";
	    $projects[$id]['initial_cq_created'] = $row['created'];
	    $projects[$id]['initial_cq_pmc'] = $row['pmc'];
	    $projects[$id]['initial_cq_checkin'] = $row['checkin'];
	    $projects[$id]['initial_cq_approved'] = $row['approved'];
	}
}

function getHttpParameters($sort=null, $top=null) {
	$parameters = array();
	foreach($_GET as $key=>$value) $parameters[$key] = $value;
	if ($top == 'all') unset($parameters['top']);
	else if ($top) $parameters['top'] = $top;

	$out = ''; $separator = '';
	foreach($parameters as $key => $value) {
		$out = "$out$separator$key=$value";
		$separator = '&';
	}
	return $out;
}

function getProjectUrl($id) {

}

function generateTable($projects, $tableDiv = "statusTable") {
    global $App;

    // TODO it'd be nice to sort out dynamic table height.
    echo "<div style=\"height:600px\" id=\"$tableDiv\"></div>";

    $columns = '';
    foreach(getColumnDefinitions() as $column) {
        $label = $column['label'];
        $columns .= "data.addColumn('string','$label');";
    }

    $rows = array();
    foreach($projects as $project) {
        $row = array();
        foreach(getColumnDefinitions() as $id => $config) {
            $value = getColumnValue($project, $id);
            $sort = (string)getSortValue($project, $id);

            $row[] = array('f' => $value, 'v' => $sort);
        }
        $rows[] = $row;
    }
    $rowsJSON = json_encode($rows);

    $js = "
        google.charts.load('current', {'packages':['table']});
        google.charts.setOnLoadCallback(drawTable{$tableDiv});

        function drawTable{$tableDiv}() {
            var data = new google.visualization.DataTable();
            $columns
            data.addRows($rowsJSON);

        var table = new google.visualization.Table(document.getElementById('$tableDiv'));

        table.draw(data, {allowHtml: true, frozenColumns: 1, width: '100%', height: '100%'});
        }
    ";

    $App->addExtraHtmlHeader("<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>");
    $App->addExtraHtmlHeader("<script type=\"text/javascript\">$js</script>");
}

function valueOrDashes($value) {
    if (!$value) return '--';
    return preg_replace('/\-/','&#8209;',$value);
}

function getColumnValue($project, $key) {
    if ($project == null) return null;
    if ($key == null) return null;

    $value = @$project[$key];
    if ($column = getColumnDefinition($key)) {
        if (isset($column['function'])) {
            $function = $column['function'];
            $value = $function($value, $key, $project);
        } else $value = valueOrDashes($value);
    }
    return $value;
}

/**
 * Determine a sort value for a value from a project
 * record. If the column provides a sort function, use
 * that sort function. Otherwise, if the value is non
 * null, return that value. Otherwise, use the display
 * function to figure out a value.
 *
 * @param unknown $project
 * @param unknown $key
 * @return NULL|string
 */
function getSortValue($project, $key) {
    if ($project == null) return null;
    if ($key == null) return null;

    $value = @$project[$key];
    if ($column = getColumnDefinition($key)) {
        if ($function = @$column['sort'])
            return $function($value, $key, $project);

        if ($value !== null) return $value;

        if ($function = $column['function'])
            return $function(null, $key, $project);
    }
    return null;
}

function getGitStatus($git) {
	switch($git) {
		case PROJECT_REPO_ALL_GIT: return 'All Git';
		case PROJECT_REPO_SOME_GIT: return 'Some Git';
		case PROJECT_REPO_NO_GIT: return 'No Git';
		default: return 'No repositories';
	}

}

function getLivelinessIcon($liveliness) {
	global $images;
	switch($liveliness) {
		case PROJECT_LIVELINESS_NEVER_ACTIVE: return $images->tools_small;
		case PROJECT_LIVELINESS_ACTIVE: return $images->active_small;
		case PROJECT_LIVELINESS_STALE: return $images->stale_small;
		case PROJECT_LIVELINESS_INACTIVE: return $images->inactive_small;
		case PROJECT_LIVELINESS_DEAD: return $images->dead_small;
	}
}

if (isset($_GET['json'])) {
	header("Content-type: application/json");
	echo json_encode(getProjectStatus());
	exit;
}

include($App->getProjectCommon());

// Add Top-Level Filters to the nav.
$Nav->addNavSeparator( "Filter", null);
foreach(Project::getTopLevelProjects() as $project) {
    $id = $project->getId();
    $name = preg_replace("/ Root$/", '', $project->getName());
    $link = "?" . getHttpParameters(null, $id);

    $Nav->addCustomNav($name, $link, "_self", 2);
}
$link = "?" . getHttpParameters(null, 'all');
$Nav->addCustomNav('All', $link, "_self", 2);

ob_start();
?>
<div id="maincontent">
<div id="midcolumn">
<h1><?php echo $pageTitle; ?></h1>

<?php generateTable(getProjectStatus()); ?>

<h4>Legend</h4>
<ul>

<li style="list-style-image: url('<?php echo $images->tools_small; ?>')">No project activity (project may be new)</li>
<li style="list-style-image: url('<?php echo $images->active_small; ?>')">Activity in the last three months</li>
<li style="list-style-image: url('<?php echo $images->stale_small; ?>')">Activity in the last six months</li>
<li style="list-style-image: url('<?php echo $images->inactive_small; ?>')">No activity for more than six months</li>
<li style="list-style-image: url('<?php echo $images->dead_small; ?>')">No activity for more than twelve months</li>
</ul>
<p>Note that subprojects are included in the determination of liveliness. A project is as lively as the most lively of its subprojects.</p>
</div>
</div>
<?php
	$html = ob_get_contents();
	ob_end_clean();
	$App->generatePage(NULL, $Menu, $Nav, $pageAuthor, $pageKeywords, $pageTitle, $html);
?>