<?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__) . "/debug.php");
trace_file_info(__FILE__);

/*
 * The regular expression pattern that is used to determine whether
 * or not a project id is valid.
 * PRIVATE: THIS FIELD IS NOT API.
 */
$projectNameSegmentPattern = "[a-zA-Z0-9\\-]+";
$projectNamePattern = "$projectNameSegmentPattern(\\.$projectNameSegmentPattern){0,2}";
define('ProjectNamePattern', $projectNamePattern);

/**
 * Answers <code>true</code> if $id represents a valid project id;
 * <code>false</code> otherwise.
 *
 * @param string $id
 *        Must not be <code>null</code>
 * @return bool
 */
function isValidProjectId($id) {
  global $projectNamePattern;

  return preg_match("/^$projectNamePattern$/", $id);
}

/**
 * This function normalizes the provided URL to a valid 'eclipse.org' HTTP
 * form.
 * Input should be a valid eclipse.org URL or a relative URL
 * (with or without a leading slash). Note that URLs that do not correspond
 * to an eclipse.org addresses, will result in a <code>null</code> result.
 *
 * Note that this is more about normalization than actual full validation;
 * only the scheme and domain are considered. The current implementation
 * only supports the http/https schemes; the specification of a port
 * is not supported. This may change in the future.
 *
 * e.g. The following URLs are all considered valid and returned in the
 * the form they are provided.
 * - http://www.eclipse.org/woolsey/para.html
 * - http://eclipse.org/woolsey/para.html
 * - http://download.eclipse.org/woolsey/para.html
 * -
 * http://git.eclipse.org/c/jetty/org.eclipse.jetty.admin.git/plain/jetty-project-plan.xml
 *
 * e.g. The following URLs will be returned as
 * http://eclipse.org/woolsey/para.html
 * - woolsey/para.html
 * - /woolsey/para.html
 *
 * Usage:
 *
 * normalizeHttpUrl('http://www.eclipse.org/woolsey/para.html');
 *
 * @param string $url
 *        Must not be <code>null</code>
 * @return string
 */
function normalizeHttpUrl($url) {
  if (preg_match('/^https?:\/\/(\w+\.)?eclipse\.org(\/.*)?$/', $url))
    return $url;
  if (preg_match('/^https?:\/\/(\w+\.)?locationtech\.org(\/.*)?$/', $url))
    return $url;
  if (preg_match('/^https?:\/\/(\w+\.)?polarsys\.org(\/.*)?$/', $url))
    return $url;

  $relative = normalizeRelativeUrl($url, 'www');
  if ($relative)
    return 'http://www.eclipse.org' . $relative;

  return null;
}

/**
 * This function normalizes the provided URL to valid file path on the
 * eclipse.org web directory.
 * Input should be a valid eclipse.org URL
 * or a relative URL (with or without a leading slash).
 *
 * e.g. The following URLs will all normalize to
 * /home/local/data/httpd/www.eclipse.org/html/woolsey/para.html
 *
 * - http://www.eclipse.org/woolsey/para.html
 * - http://eclipse.org/woolsey/para.html
 * - http://localhost/woolsey/para.html
 * - woolsey/para.html
 * - /woolsey/para.html)
 *
 * Note that URLs that do not correspond to eclipse.org addresses, will
 * result in a <code>null</code> result.
 *
 * Usage:
 *
 * normalizeFilePathUrl('http://www.eclipse.org/woolsey/para.html');
 *
 * @param string $url
 *        Must not be <code>null</code>
 * @return string
 */
function normalizeFilePathUrl($url) {
  global $_SERVER;

  $relative = normalizeRelativeUrl($url);
  if (!$relative)
    return null;

  return $_SERVER['DOCUMENT_ROOT'] . $relative;
}

/**
 * This function normalizes the provided URL to a relative path.
 * Input should be a valid eclipse.org URL or a relative URL
 * (with or without a leading slash).
 *
 * e.g. The following URLs will all normalize to
 * /woolsey/para.html
 *
 * - http://www.eclipse.org/woolsey/para.html
 * - http://eclipse.org/woolsey/para.html
 * - http://localhost/woolsey/para.html
 * - woolsey/para.html
 * - /woolsey/para.html)
 *
 * Note that URLs that do not correspond to eclipse.org addresses, will
 * result in a <code>null</code> result.
 *
 * Usage:
 *
 * normalizeRelativeUrl('http://www.eclipse.org/woolsey/para.html');
 *
 * @param string $url
 *        Must not be <code>null</code>
 * @return string
 */
function normalizeRelativeUrl($url) {
  if (!$url)
    return null;

  $url = trim($url);

  $pattern_word = '\w[\w-]*';
  $pattern_segment = "$pattern_word(\\.$pattern_word)*";
  $pattern_relative_part = "$pattern_segment(\\/$pattern_segment)*\\/?";
  $pattern_relative_url = "/^\\/?($pattern_relative_part)$/";
  $pattern_http_url = "/^http:\\/\\/(www\\.)?eclipse\\.org\\/($pattern_relative_part)$/";
  $pattern_http_local_url = "/^http:\\/\\/localhost\\/($pattern_relative_part)$/";

  if (preg_match($pattern_relative_url, $url, $matches1)) {
    return '/' . $matches1[1];
  }
  else
    if (preg_match($pattern_http_url, $url, $matches2)) {
      return '/' . $matches2[2];
    }
    else
      if (preg_match($pattern_http_local_url, $url, $matches3)) {
        return '/' . $matches3[1];
      }
      else {
        trace("The url ($url) cannot be normalized.");
        return null;
      }
}

/**
 * If the user is logged in and is either an Eclipse committer
 * or a staff member of the Eclipse Foundation, this method
 * returns without side effect. If there is no currently logged
 * in user, the user is redirected to the login page. If the
 * currently logged in user is not a committer or an employee,
 * they are redirected to the /project page and the exit()
 * function is called (i.e. execution of the caller is truncated).
 *
 * This function assumes that the $App variable exists and has been
 * assigned an instance of the App class (from app.class.php).
 *
 * @deprecated
 * @see callIfNotCommitter()
 *
 * @param Tracer $trace
 *        (optional)
 * @return Friend
 */
function mustBeCommitter($trace = null) {
  global $App;
  if ($App->devmode)
    return;

  require_once ($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/classes/friends/friend.class.php");
  require_once ($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/eclipseenv.class.php");

  $Session = $App->useSession("optional");
  $friend = $Session->getFriend();

  // FIXME Hack: Foundation employees have privileged access.
  // TODO There may be a better way to do this.
  if ($friend && preg_match('/^.+@eclipse-foundation\.org$/', $friend->getEmail())) {
  	return $friend;
  }

  $EclipseEnv = new EclipseEnv();
  $domain = $EclipseEnv->getEclipseEnv();

  if (!$friend->getLDAPUID()) {
    header("Location: https://" . $domain["accounts"] . "/user/login?takemeback=" . $_SERVER['SCRIPT_URI']);
    exit();
  }

  if (!$trace)
    $trace = trace("Must be committer");
  $trace->trace("UUID: " . $friend->getLDAPUID());

  if (!$friend->getIsCommitter()) {
    header("Location: /projects");
    exit();
  }

  $trace->trace("User is a committer.");

  return $friend;
}

/**
 * Test to see if the user is a committer, and execute
 * the callable if they are not.
 *
 * @param callable $function
 */
function callIfNotCommitter($function) {
	global $App;
	if ($App->devmode) {
		return;
	}

	$Session = $App->useSession("required");
	$friend = $Session->getFriend();

	// TODO There may be a better way to do this.
	if (preg_match('/^.+@eclipse-foundation\.org$/', $friend->getEmail())) {
		return;
	}

	if (!$friend->getIsCommitter()) {
		call_user_func($function);
	}
}

/**
 * This function forces a login event if the current user is not
 * logged in.
 * If the logged in user is not an Eclipse Foundation
 * employee, they are redirected to the /projects/ page. It must
 * be called before any HTML is written to the output stream.
 *
 * This function assumes that the $App variable exists and has been
 * assigned an instance of the App class (from app.class.php).
 *
 * @return Friend
 */
function mustBeFoundationEmployee() {
  global $App;
  if ($App->devmode)
    return;

  $session = $App->useSession('required');
  $friend = $session->getFriend();

  // TODO There may be a better way to do this.
  if (!preg_match('/^.+@eclipse-foundation\.org$/', $friend->getEmail())) {
    header("Location: /projects");
    exit();
  }

  return $friend;
}

/**
 * This function basically throws a fit if the caller is
 * coming from anywhere outside of the EF.
 * It determines
 * whether or not to grant access based on the IP Address.
 */
function mustBeEclipseFoundationCaller() {
	global $App;

	$App->preventCaching();
	$ip = $App->getRemoteIPAddress ();
	$patterns = array (
			'198.41.30.', // 198.41.30.192/26
			'99.240.80.',
			'172.25.', // 172.25.0.0/16
			'172.30.', // 172.30.0.0/16
			'127.0.0.1',
			'::1'
	);
	$match = preg_replace ( '/\./', '\.', implode ( '|', $patterns ) );
	if (preg_match ( "/^($match)/", $ip ))
		return;
	echo "{$ip} is an invalid caller\n";
	exit ();
}

function getUrlContents($url) {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  $page = curl_exec($ch);
  curl_close($ch);
  return $page;
}

function implodeWithConjunction($values, $conjunction = 'and', $start = 0) {
 $end = count($values) - 1;
 if ($start > $end) {
  return;
 } elseif ($start == $end) {
   return $values[$start];
 } elseif ($end - $start == 1) {
    return $values[$start] . ', ' . $conjunction . ' ' . $values[$end];
 } else {
     return $values[$start] . ', ' . implodeWithConjunction($values, $conjunction, $start + 1);
 }
}

function renderAsHeaderComment($string, $length=80) {
 $output = array();
 $output[] = '/' . str_repeat('*', $length);
 foreach(explode("\n", $string) as $line) {
  foreach(explode("\n", wordwrap($line, $length-5)) as $fragment) {
   $output[] = ' * ' . $fragment;
  }
 }
 $output[] = ' ' . str_repeat('*', $length) . '/';

 return implode("\n", $output);
}

function compareSemanticVersion($a, $b) {
   $va = explode('.', $a);
   $vb = explode('.', $b);

   $max = 5;
   while ($max-- > 0) {
	    $ca = current($va);
	    $cb = current($vb);

	    // FALSE means that we've run out of terms. If we're out of terms,
	    // assume that the value is zero. This allows us to, for example,
	    // meaningfully and correctly compare '3.0' and '3.0.0'.
	    if ($ca === FALSE) $ca = 0;
		if ($cb === FALSE) $cb = 0;

		// Compare as integers rather than strings.
		$ca = (int) $ca;
		$cb = (int) $cb;

		if ($ca > $cb) {
			return 1;
		} elseif ($cb > $ca) {
			return -1;
		}

		next($va);
		next($vb);
   }

   return 0;
}

/**
 * This function answers the id of the Eclipse project that produces the bits
 * with the provided ClearlyDefined coordinates.
 *
 * FIXME This function doesn't belong here.
 */
function getEclipseProjectFor($id) {
	// FIXME We should draw on a data source of some kind rather than hardcoding.
	$map = array(
			'*/*/p2.p2-installable-unit/org.eclipse.rcp_root/*' => 'eclipse.platform',
			'*/*/p2.p2-installable-unit/org.eclipse.platform_root/*' => 'eclipse.platform',

			'*/*/p2.p2-installable-unit/org.eclipse.rcp.*/*' => 'eclipse.platform',
			'*/*/p2.p2-installable-unit/org.eclipse.platform.*/*' => 'eclipse.platform',

			'*/*/org.glassfish.grizzly/grizzly-npn*/2.0.0+' => 'ee4j.grizzly',
			'*/*/org.glassfish.grizzly/grizzly-thrift/1.3.15+' => 'ee4j.grizzly',
			'*/*/org.glassfish.grizzly/grizzly-memcached/1.3.19+' => 'ee4j.grizzly',
			'*/*/org.glassfish.grizzly/*/2.4.4+' => 'ee4j.grizzly',
			'*/*/org.glassfish.hk2*/*/2.6+' => 'ee4j.glassfish',
			'*/*/org.glassfish.mq/*/5.1.3+' => 'ee4j.openmq',
			'*/*/org.glassfish.tyrus*/*/1.15+' => 'ee4j.tyrus',
			'*/*/org.glassfish/jakarta.json/*' => 'ee4j.jsonp',

			'*/*/org.eclipse.parsson/*/*' => 'ee4j.parsson',

			'*/*/org.glassfish/jsonp-jaxrs/1.1.5+' => 'ee4j.jsonp',

			'*/*/org.glassfish.jersey*/*/2.28+' => 'ee4j.jersey',

			'*/*/jakarta.activation/*/*' => 'ee4j.jaf',
			'*/*/jakarta.annotation/*/*' => 'ee4j.ca',
			'*/*/jakarta.servlet/*/*' => 'ee4j.servlet',
			'*/*/jakarta.ws.rs/*/*' => 'ee4j.jaxrs',
			'*/*/jakarta.xml.bind/*/*' => 'ee4j.jaxb',

			'*/*/com.sun.activation/jakarta.activation/*' => 'ee4j.jaf',
			'*/*/org.eclipse.aether/*/*' => 'technology.aether',
			'*/*/org.eclipse.dash/*/*' => 'technology.dash',
			'*/*/org.eclipse.sisu/*/*' => 'technology.sisu',

			'*/*/@theia/*/*' => 'ecd.theia'

	);

	// This list is stable, I think. I believe that we can expand this out and
	// just include it in whatever data source we end up choose to use to represent
	// this information.
	$platform = array('platform', 'test', 'releng', 'webdav', 'externaltools', 'rcp', 'core', 'debug', 'help', 'ui', 'sdk', 'team', 'text', 'ltk', 'osgi', 'search', 'compare', 'update', 'ant', 'jface', 'swt', 'jsch', 'cvs', 'tomcat', 'target', 'ftp', 'license');
	foreach ($platform as $fragment) {
		$map["*/*/p2.p2-installable-unit/org.eclipse.{$fragment}.*/*"] = 'eclipse.platform';
	}

	$parts = explode('/', $id);
	foreach($map as $pattern => $project) {
		$bits = explode('/', $pattern);
		if (count($bits) < 5) continue;
		if (!fnmatch($bits[0], $parts[0])) continue;
		if (!fnmatch($bits[1], $parts[1])) continue;
		if (!fnmatch($bits[2], $parts[2])) continue;
		if (!fnmatch($bits[3], $parts[3])) continue;
		if ($bits[4] == '*') return $project;

		// If the version information ends with a plus (+), then we look for
		// matches that are the specified version and greater. Otherwise,
		// we look for straight up matches (exact isn't the right word here,
		// since the compareSemanticVersion function compares equivalence, so, e.g.,
		// "1.0" and "1.0.0" are considered to match).
		//
		// Note that we don't do wildcard/glob matches within versions (i.e.,
		// we do match '*' to mean "any version", but something like '1.*.8' isn't supported).
		if (preg_match('/^(?<version>.*)\+$/', $bits[4], $matches)) {
			if (compareSemanticVersion($matches['version'], $parts[4]) <= 0) return $project;
		} elseif (compareSemanticVersion($bits[4], $parts[4]) == 0) return $project;
	}

	return null;
}
?>