<?php
/**
 * Copyright (c) Eclipse Foundation and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 */

require_once dirname ( __FILE__ ) . '/Project.class.php';
require_once dirname ( __FILE__ ) . '/License.class.inc';
require_once dirname ( __FILE__ ) . '/common.php';
require_once dirname ( __FILE__ ) . '/debug.php';

/**
 * The ProjectStatusReporter class provides behaviour to load
 * information about some subset of the projects, and then
 * extract and provide that information in various ways.
 * Several "alerts" and "columns" are defined, each of which knows how
 * to extract and present some piece of the data.
 *
 * An instance is loaded with various "collectors", "alerts" and "values".
 *
 * Collectors are a means to load an instance with data; the primary
 * intent being to preload and cache data rather than compute/load (and
 * potentially recompute/load) as it is needed.
 *
 * Alerts are, essentially, a message and a callback that determines
 * whether or not to display the message. Alters may be used, for
 * example, to identify whether or not the project uses and old version
 * of a license and so must be updated. The callback associated with
 * an alert is a callable that takes an instance of Project as a parameter.
 *
 * Values provide a means of extracting values to display. A function
 * may be provided to compute the value. In the absense of a function,
 * the array key is used as an index into the values cached for the
 * project.
 */
class ProjectStatusReporter {
	var $project;
	var $data;
	var $alerts;
	var $values;
	var $charts;

	function __construct($id) {
		$this->collectors = array(
			'commits' => function($id) {
				$sql = "
					select distinct
						p.id as id,
						min(date(ps.initialCommit)) as commits_initial,
						max(date(ps.latestCommit)) as commits_latest,
						sum(distinct ps.totalCommits) as commits
					from Project as p
						join ProjectRollup as pr on p.id=pr.project
						left join ProjectStats as ps on pr.subproject=ps.project
					where p.id = ':id:'
					group by p.id";

				$result = array();
				query ( 'dashboard', $sql, array(':id:' => $id), function ($row) use (&$result) {
					$result = $row;
				});
				return $result;
			},
			'reviews' => function($id) {
				$sql = "
					select distinct
						max(rev.date) as review,
						max(rev.date) >= date_sub(now(), interval 1 year) as goodstanding
					from Project as p
						left join ProjectReviews as rev on p.id=rev.project
							and rev.type in ('progress', 'release','graduation', 'creation', 'other')
							and rev.status = 'success'
					where p.id = ':id:'";

				$result = array();
				query ( 'dashboard', $sql, array(':id:' => $id), function ($row) use (&$result) {
					$result = $row;
				} );
				return $result;
			},
			'active' => function($id) {
				$sql = "
					select distinct
						count(distinct pca.company) as organizations,
						count(distinct pda.login) as contributors
					from Project as p
						left join ProjectCompanyActivity as pca on p.id=pca.project
						left join ProjectCommitterActivity as pda on p.id=pda.project
					where p.id = ':id:'";

				$result = array();
				query ( 'dashboard', $sql, array(':id:' => $id), function ($row) use (&$result) {
					$result = $row;
				} );
				return $result;
			},
			'license' => function($id) {
				$licenses = License::getLicensesForProject($id);
				$spdx = License::getSPDXExpression($licenses);
				return array('license' => $spdx);
			}
		);
		$this->alerts = array(
				'archived' => array(
						'message' => 'The project is archived',
						'when' => function($project) {
							return $project->isArchived();
						}
				),
				'since' => array(
						'message' => 'The project has not been provisioned',
						'when' => function($project) {
							return $project->getProvisionedDate() == null;
						}
				),
				'provisioned' => array(
						'message' => 'The project was provisioned in the last three months',
						'when' => function($project) {
								if (!$project->getProvisionedDate()) return false;
								return $project->getProvisionedDate() > strtotime('-3 months');
							}
						),
				'epl-1.0' => array(
						'message' => 'The project uses the EPL-1.0',
						'when' => function ($project) {
							$licenses = License::getLicensesForProject($project->getId());
							foreach ($licenses as $license) {
								if ($license->getId() == 'EPL-1.0') return true;
							}
							return false;
						}
				),
				'dormant' => array(
						'message' => 'The project appears to be dormant',
						'when' => function ($project) {
							$latest = $this->getProjectData('commits_latest');
							return strtotime($latest) < strtotime('-1 year');
						}
				),
				'review' => array(
						'message' => 'The project is due for a progress review.',
						'when' => function($project) {
							return !$this->getProjectData('goodstanding');
						}
				),
				'no_project_lead' => array(
						'message' => 'The project has no project leads',
						'when' => function ($project) {
							return !$project->hasProjectLeads();
						}
				),
				'no_committers' => array(
						'message' => 'The project has no committers',
						'when' => function ($project) {
							return !$project->hasCommitters();
						}
				)
		);

		/*
		 * Note that some of the "values" have a "sort" entry. This is from a
		 * previous use of the ProjectStatusReporter that rendered values in
		 * a table with the ability to sort the table on any column that provides
		 * a "sort" entry. The basic idea being that the function answers the
		 * sort value of a particular column from a particular project.
		 * The values are currently ignored; I decided to leave them in for
		 * now as I may opt to do something similar again.
		 */

		$this->values = array (
				'url' => array (
						'label' => 'Project Page (PMI)',
						'function' => function ($value, $key, $project) {
							return "<a href=\"$value\">{$project['name']}</a>";
						}
				),
				'tlp' => array (
						'label' => 'Top-Level',
						'function' => function ($value, $key, $project) {
							$tlp = $project['project']->getTopLevelProject();
							return "<a href=\"{$tlp->getUrl()}\">{$tlp->getFormalName()}</a>";
						}
				),
				'started' => array (
						'label' => 'Started',
						'function' => function($value, $key, $data) {
							if (!$project = $data['project']) return null;
							if (!$started = $project->getProvisionedDate()) return null;
							return date('Y-m-d', $started);
						}
				),
				'license' => array (
						'label' => 'License'
				),
				'openchain' => array(
						'label' => 'OpenChain Compliance',
						'function' => function($value, $key, $project) {
							if ($project['goodstanding']) return '2.1';
							return 'Unverified';
						}
				),
				'specification' => array (
						'label' => 'Specification Working Group',
						'function' => function ($value, $key, $project) {
							return $project['project']->getSpecificationWorkingGroupName();
						}
				),
				'phase' => array (
						'label' => 'Phase',
						'function' => function ($value, $key, $project) {
							if ($project['project']->isInIncubationPhase ()) return 'Incubating';
							if ($project['project']->isArchived()) return 'Archived';
							return'Regular';
						}
				),
				'review' => array(
						'label' => 'Last Review'

				),
				'contributors' => array (
						'label' => 'Active Contributors',
						'description' => 'Based on commits over the last three months'
				),
				'organizations' => array (
						'label' => 'Active Member Companies',
						'description' => 'Based on commits over the last three months'
				),
				'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 ( (int)$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 self::getTimeSince ( $latest );
							return '--';
						},
						'sort' => function ($value, $key, $project) {
							if ($latest = @$project ['commits_latest'])
								return ( int ) (time () - strtotime ( $latest ));
							return 0;
						},
						'class' => 'column-align-right'
				)
		);
		$this->charts = array(
			'project_activity' => function(Project $project) {
				return ChartBuilder::named ( "project_activity_" . rand () )
					->title ( "Commit Activity" )
					->description ( "Overall committer activity by month based on commits made
						against project repositories from :start to :end." )
					->query ( 'dashboard', "
						select
							periods.period as period,
							if (commits.count is null, 0, commits.count) as count
						from (
							select distinct period
							from ProjectCommitActivity
							where
								period
									between (
										select
											if(max(period) < date_format(':start','%Y%m'),
												date_format(':end','%Y%m'),
												greatest(min(period), date_format(':start','%Y%m')))
										from ProjectCommitActivity
										where project=':id')
									and date_format(':end','%Y%m')) as periods
						left join
							ProjectCommitActivity as commits
							on (periods.period = commits.period and commits.project=':id')
						order by period
					" )
					->substitute ( ':id', $project->getId () )
					->substitute ( ':start', (new DateTime())->modify('-4 Years')->format('Y-m-d') )
					->substitute ( ':end', (new DateTime())->modify('-1 Months')->format('Y-m-d') )
					->column ( 'Month', 'period', 'string', function ($value) {
						return asYearMonth ( $value );
					} )
					->column ( 'Commits', 'count', 'number' )
					->columnChart ()
					->height ( 400 )
					->width ( 640 )
					->option ( 'legend', 'none' );
			},
			'project_contributors' => function(Project $project) {
				return ChartBuilder::named('project_contributors_' . rand())
					->title("Project Contributors by Quarter")
					->description(
							"Quarterly statistics on contribution (distinct contributors).")
					->query('dashboard', "
						select
							quarter,
							contributors,
							committers,
							companies
						from ProjectQuarterlyContributionSummary
						where project=':id'
							and quarter
								between concat(year(':start'),'Q', quarter(':start'))
								and concat(year(':end'),'Q', quarter(':end'))
					")
					->column('Quarter', 'quarter', 'string', function($value) {return asYearMonth($value);})
					->column('Contributors', 'contributors', 'number')
					->column('Committers', 'committers', 'number')
					->column('Companies', 'companies', 'number')
					->substitute ( ':id', $project->getId () )
					->substitute ( ':start', '2000-01-01')
					->substitute ( ':end', (new DateTime())->modify('-3 Months')->format('Y-m-d'))
					->height ( 400 )
					->width ( 640 );
			}
		);
		$this->loadProject($id);
	}

	function values($function) {
		foreach ( $this->values as $id => $config ) {
			call_user_func($function, new ProjectStatusReporterColumn ( $id, $config, $this->data ) );
		}
	}

	function charts($function) {
		foreach ( $this->charts as $callable ) {
			$builder = call_user_func($callable, $this->project);
			$builder->titleString("<h4>:title</h4>");
			call_user_func($function, $builder);
		}
	}

	/**
	 * Generate a list of alerts for a particular project.
	 *
	 * @param Project $project
	 * @return string[]
	 */
	function alerts() {
		if ($this->project->isTopLevel()) return;

		$alerts = array();
		foreach ( $this->alerts as $config ) {
			if (call_user_func ($config['when'], $this->project)) {
				$alerts[] = $config['message'];
			}
		}
		return $alerts;
	}

	public function getColumnDefinition($key) {
		return $this->values [$key];
	}

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

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

	/**
	 * This function answers the value (if any) with a named
	 * index associated with a particular instance of Project.
	 * The values that are available are dependent on the data
	 * that is loaded into the instance.
	 *
	 * @param Project $project
	 * @param string $key
	 * @return mixed|NULL
	 */
	private function getProjectData($key) {
		return @$this->data[$key];
	}

	private function loadProject($id) {
		$project = Project::getProject($id);

		$this->project = $project;
		$this->data = 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 ()
		);

		// FIXME Experimental: call_user_func does pass-by-value.
		// Need to sort out pass-by-reference.
		foreach($this->collectors as $collector) {
			$this->data += call_user_func($collector, $id);
		}
	}

	/**
	 * This function answers a string containing the quoted ids for
	 * the projects.
	 *
	 * @param mixed $projects
	 * @return string
	 */
	private function getProjectIds(&$projects) {
		$ids = array ();
		foreach ( $projects as $project ) {
			$ids [] = "'{$project['id']}'";
		}
		return implode ( ',', $ids );
	}

	public static function valueOrDashes($value) {
		if (! $value)
			return '--';
		return $value;
	}
}
class ProjectStatusReporterColumn {
	var $id, $config, $data;

	public function __construct($id, $config, $data) {
		$this->id = $id;
		$this->config = $config;
		$this->data = $data;
	}

	public function getTitle() {
		return $this->config ['label'];
	}

	public function getDescription() {
		return $this->config ['description'];
	}

	public function getValue() {
		$value = @$this->data[$this->id];
		if (isset ( $this->config ['function'] )) {
			$function = $this->config ['function'];
			$value = call_user_func($function, $value, $this->id, $this->data );
		}

		return ProjectStatusReporter::valueOrDashes ( $value );
	}
}