<?php
/**
 * Copyright (c) 2020 Eclipse Foundation.
 *
 * 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/
 *
 * Contributors:
 * Eric Poirier (Eclipse Foundation) - initial API and implementation
 *
 * SPDX-License-Identifier: EPL-2.0
 */

require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/session.class.php");
require_once("/home/data/httpd/eclipse-php-classes/system/ldapconnection.class.php");

class DownloadDirectory {

  /**
   * App object
   */
  private $App;

  /**
   * Processing paths
   */
  private $processing_paths = array();

  /**
   *
   * The directory to work with
   */
 private $basedir = "";

  /**
   * Person ID
   */
  private $person_id = "";

  /**
   * LDAP Group
   */
  private $ldap_group = NULL;

  /**
   * User is committer
   */
  private $user_is_committer = NULL;

  private $request_uri = "";

  private $oomph_size_index_base = "https://download.eclipse.org/oomph/archive/";
  private $oomph_index_html = "";

  public function __construct() {
    $this->App = new App();

  }

  /**
   * Get current path
   *
   * @param string $file
   *
   * @return string
   */
  private function _getPath($file) {
    if (empty($file)) {
      return "";
    }

    $file = $this->App->checkPlain($file);
    $current_dir_path = $this->_getUri();

    // Remove the last directory from the path
    $current_dir_path_array = explode('/', $current_dir_path);
    $count = count($current_dir_path_array);
    unset($current_dir_path_array[$count - 1]);

    // Scan through the parent's current directory to find out
    // the proper way to write the current directory.
    $parent_path = implode('/', $current_dir_path_array);
    $parent_path = rtrim($parent_path, '/') . "/";

    // Validate if we're dealing with an existing file or directory
    $file_path = $parent_path . $file;
    if (is_file($this->getCurrentDirectory() . $file) || is_dir($this->getCurrentDirectory() . $file)) {
      return $file_path;
    }

    return "";
  }

  /**
   * Get the output HTML of a file
   *
   * @return string
   */
  private function _getFileOutput($file) {

    if (empty($file)) {
      return "";
    }

    $path = $this->_getPath($file);
    $processing_paths = $this->_getProcessingRequests();

    $input_disabled = '';
    $suffix_text = '';

    # Get date/time
    $file_datetime = "";
    $file_size = "";
    if (file_exists($this->basedir . $file)) {
      $file_datetime = date("Y-m-d H:i", filemtime($this->basedir . $file));
      $file_size = $this->human_filesize(filesize($this->basedir . $file), 1);
    }


    if (array_key_exists($path, $processing_paths)) {
      $action = 'archived';
      if ($this->_isArchiveDomain()) {
        $action = 'deleted';
      }
      $suffix_text = '<span class="small">(This file is being ' . $action . ')</span>';

      # examine the token (return value from the handler
      if(!empty($processing_paths[$path])) {
          $suffix_text = '<span class="small">(File cannot be ' . $action . ': ' . $processing_paths[$path] . '. Please contact webmaster.)</span>';
      }
      $input_disabled = 'disabled="disabled"';
    }
    $icon = "<img src='//dev.eclipse.org/small_icons/actions/edit-copy.png' />";

    # build download link. Send to mirrors if it's a binary archive and it's not on archive.e.o.
    $link = "<a href='" . $path . "'> " . $file . "</a>";
    if (!$this->_isArchiveDomain() && preg_match('/(zip|jar|xz|gz|tar|iso)$/', $file)) {
      $link = "<a href='https://www.eclipse.org/downloads/download.php?file=" . $path . "'>" . $file . "</a>";
    }
    $checkbox = "";
    if (!empty($path) && $this->_userIsCommitterOnProject()) {
      $checkbox = '<input ' . $input_disabled . ' type="checkbox" name="paths_to_archive[]" value="'. $path .'" />';
    }
    return '<tr><td>' . $checkbox . '</td><td>' . $icon . ' ' . $link . '</td><td style="text-align: right; padding-right:15px;"> ' . $file_size . ' </td><td>' . $file_datetime . '</td><td>' . $suffix_text . '</td></tr>';
  }

  /**
   * Get the output HTML of a folder
   *
   * @return string
   */
  private function _getFolderOutput($directory) {

    if($directory === ".") {
      return "";
    }

    $path = $this->_getPath($directory);
    $processing_paths = $this->_getProcessingRequests();

    $input_disabled = '';
    $suffix_text = '';

    # Get date/time
    $file_datetime = "";
    if (file_exists($this->basedir . $directory) && $directory !== "..") {
      $file_datetime = date("Y-m-d H:i", filemtime($this->basedir . $directory));
    }
    $size = $this->_getOomphDirectorySize($directory);

    if (array_key_exists($path, $processing_paths)) {
      $action = 'archived';
      if ($this->_isArchiveDomain()) {
        $action = 'deleted';
      }
      $suffix_text = '<span class="small">(This folder is being ' . $action . ')</span>';

      # examine the token (return value from the handler
      if(!empty($processing_paths[$path])) {
        $suffix_text = '<span class="small">(Folder cannot be ' . $action . ': ' . $processing_paths[$path] . '. Please contact webmaster.)</span>';
      }
      $input_disabled = 'disabled="disabled"';
    }
    $icon = "<img src='//dev.eclipse.org/small_icons/places/folder.png' />";
    $link = "<a href='" . $path . "'> " . $directory . "</a> ";

    $checkbox = "";
    if (!empty($path) && $directory !== ".." && $this->_userIsCommitterOnProject()) {
      $checkbox = '<input ' . $input_disabled . ' type="checkbox" name="paths_to_archive[]" value="'. $path .'">';
    }

    return '<tr><td>' . $checkbox . '</td><td>' . $icon . ' ' . $link . '</td><td style="text-align: right; padding-right:15px;"> ' . $size . ' </td><td>' . $file_datetime . '</td><td>' . $suffix_text . '</td></tr>';
  }

  /**
   * Get Person ID from Session
   *
   * @return string
   */
  private function _getPersonID() {
    if (empty($this->person_id)) {
      $Session = new Session();
      $Friend = $Session->getFriend();
      $this->person_id = $Friend->getUID();
    }
    return $this->person_id;
  }

  /**
   * Get all the processing requests from account_requests table
   *
   * @return array
   */
  private function _getProcessingRequests() {

    if (!empty($this->processing_paths)) {
      return $this->processing_paths;
    }

    $action = "DOWNLOAD_ARCHIVE";
    if ($this->_isArchiveDomain()) {
      $action = "DOWNLOAD_DELETE";
    }

    $sql = "SELECT password as Path, token
      FROM account_requests
      WHERE fname = " . $this->App->returnQuotedString($this->App->sqlSanitize($action)) . "
      AND lname = " . $this->App->returnQuotedString($this->App->sqlSanitize($action));
    $result = $this->App->eclipse_sql($sql);

    if (empty($result)) {
      $this->processing_paths;
    }

    while($myrow = mysql_fetch_array($result)) {
      $this->processing_paths[$myrow['Path']] = $myrow['token'];
    }
    return $this->processing_paths;
  }

  /**
   * Get uri
   *
   * @return string
   */
  private function _getUri() {
    if (empty($this->request_uri)) {
      # Support adding /listing to a directory that contains an index file
      # See: errors/404.php
      $this->request_uri = preg_replace('#listing$#', '', $_SERVER['REQUEST_URI']);
    }
    return str_replace("?d", "", $this->request_uri);
  }
  

  /**
   * Get the url of the current directory
   *
   * @return string
   */
  public function getCurrentDirectory() {
    return $_SERVER['DOCUMENT_ROOT'] . rawurldecode($this->_getUri());
  }

  /**
   * Get the project ID based on the group owner of the folder
   *
   * @return string
   */
  private function _getProjectID() {
    $group = $this->getLdapGroupByGid(filegroup($this->basedir));

    if (empty($group)) {
      return "";
    }
    return $group;
  }

  /**
   * Insert into account_requests table
   *
   * @return bool
   */
  private function _insertRequest() {
    if (empty($_POST['paths_to_archive'])) {
      return FALSE;
    }

    $action = "DOWNLOAD_ARCHIVE";
    if ($this->_isArchiveDomain()) {
      $action = "DOWNLOAD_DELETE";
    }

    foreach ($_POST['paths_to_archive'] as $path) {
      $sql = "SELECT
              email
              FROM account_requests
              WHERE email = " . $this->App->returnQuotedString($this->App->sqlSanitize($this->_getPersonID())) . "
              AND password = ". $this->App->returnQuotedString($this->App->sqlSanitize($path));
      $result = $this->App->eclipse_sql($sql);
      while ($row = mysql_fetch_array($result)) {
        if (!empty($row['email'])) {
          return FALSE;
        }
      }

      $sql = "INSERT INTO account_requests (
          email,
          new_email,
          fname,
          lname,
          password,
          ip,
          req_when,
          token
        )
          VALUES (
          " . $this->App->returnQuotedString($this->App->sqlSanitize($this->_getPersonID())) . ",
          NULL,
          " . $this->App->returnQuotedString($this->App->sqlSanitize($action)) . ",
          " . $this->App->returnQuotedString($this->App->sqlSanitize($action)) . ",
          " . $this->App->returnQuotedString($this->App->sqlSanitize($path)) . ",
          " . $this->App->returnQuotedString($this->App->sqlSanitize($this->App->getRemoteIPAddress())) . ",
          NOW(),
          NULL
          )";
      $this->App->eclipse_sql($sql);
    }
  }

  /**
   * Check if the current domain is archive.eclipse.org
   *
   * @return bool
   */
  private function _isArchiveDomain() {
    if (!empty($_SERVER['HTTP_HOST']) && strpos($_SERVER['HTTP_HOST'], 'archive.eclipse.org') !== FALSE) {
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Check if the user is a committer on a specific project
   *
   * @return bool
   */
  private function _userIsCommitterOnProject() {

    if (!is_null($this->user_is_committer)) {
      return $this->user_is_committer;
    }

    $sql = "SELECT count(1) as count
      FROM PeopleProjects
      WHERE PersonID = " . $this->App->returnQuotedString($this->App->sqlSanitize($this->_getPersonID())) . "
      AND ProjectID = " . $this->App->returnQuotedString($this->App->sqlSanitize($this->_getProjectID())) . "
      AND Relation = " . $this->App->returnQuotedString("CM") . "
      AND (InactiveDate IS NULL OR InactiveDate = '0000-00-00')";
    $result = $this->App->foundation_sql($sql);
    $this->user_is_committer = FALSE;
    while($myrow = mysql_fetch_array($result)) {
      if ($myrow['count']) {
        $this->user_is_committer = TRUE;
      }
    }

    return $this->user_is_committer;
  }



  /**
   * Get the Form ouput
   *
   * @return string
   */
  public function getFormOutput($files, $dirs, $basedir=null) {

    if($basedir === null) {
      $basedir = $this->getCurrentDirectory();
    }
    $this->basedir = $basedir;

    if(preg_match('#/localsite/(.*).org/(.*)#', $basedir, $matches)) {
      $site = $matches[1];
      $basepath = "/" . $matches[2];
      $this->_getOomphDirectoryHTML($site, $basepath);
    }

    $output = "";
    $html_checkboxes = array();
    foreach ($dirs as $directory) {
      if($directory === ".") {
        continue;
      }

      if ($directory === ".." || $this->_userIsCommitterOnProject() === FALSE) {
        $output .= $this->_getFolderOutput($directory);
        continue;
      }

      $html_checkboxes[] = $this->_getFolderOutput($directory);
    }

    foreach ($files as $file) {
      if ($this->_userIsCommitterOnProject() === FALSE) {
        $output .= $this->_getFileOutput($file);
      }
      $html_checkboxes[] = $this->_getFileOutput($file);
    }

    if ($this->_userIsCommitterOnProject() === FALSE) {
      return "<table class='.table' style='width:100%; font-family: monospace; font-size: medium;'>" . $output . "</table>";
    }

    // Now that we know that the current user is a committer for this project,
    // we can safely insert a new request on page reload
    $this->_insertRequest();

    $output .= '<form class="downloads-directory" method="post" action="/errors/filehandler.php">';
    $output .= "<table class='.table' style='width:100%; font-family: monospace;'>" . implode("", $html_checkboxes) . "</table>";

    $button_text = 'Move selected to archive.eclipse.org';
    $button_class = 'btn-primary';
    if ($this->_isArchiveDomain()) {
      $button_text = 'Delete selected permanently';
      $button_class = 'btn-danger';
    }

    $output .= '<ul class="list-inline">';
    $output .= '<li><input id="deletesubmit" class="btn btn-xs ' . $button_class . '" type="submit" value="' . $button_text . '" /></li>';
    if (!$this->_isArchiveDomain()) {
      $App = new App();
      $archive_url = str_replace("download.eclipse.org","archive.eclipse.org", $App->getCurrentURL());
      $output .= '<li><a class="btn btn-success btn-xs" href="'. $archive_url .'">Go to Archives</a></li>';
    }
    $output .= '</ul>';
    $output .= "</form>";
    if (!$this->_isArchiveDomain()) {
      $output .= "<p><b>PLEASE NOTE:</b> You can safely move content, even entire p2 repositories, to Archives. Links will continue to work.</p>";
    }
    $output .= "<span class='small'>File and folder operations make take several seconds to complete. Refresh the page to get current status.</span>";
    return $output;
  }

  /**
   * Get the LDAP Group name, by gid
   *
   * @return string
   */
  public function getLdapGroupByGid($gid) {
    if (!is_null($this->ldap_group)) {
      return $this->ldap_group;
    }
    $LDAPConnection = new LDAPConnection();
    $this->ldap_group = $LDAPConnection->getGroupByGid($gid);
    return $this->ldap_group;
  }

  public function human_filesize($bytes, $decimals = 2) {
    $sz = ' kMGTP';
    $factor = floor((strlen($bytes) - 1) / 3);
    if($factor == 0) {
      $decimals = 0;
    }
    return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
  }


  /**
   * 
   * @param String $_site download.eclipse or archive.eclipse
   * @param String $_base /path/to/the/dir relative to the base directory containing downloads
   */
  private function _getOomphDirectoryHTML($_site, $_base) {
    $this->oomph_index_html = file_get_contents($this->oomph_size_index_base . $_site . $_base);
  }

  /**
   * 
   * @param String $dirname the directory name to look up, no slashes.
   * @return String 
   */
  private function _getOomphDirectorySize($dirname) {
    if(!empty($this->oomph_index_html)) {
      # <tr><td><a id='2020-12' href='2020-12/index.html'>2020-12</a></td><td>474.3M</td><td>17.15%</td><td>2021-03-30</td></tr>
      if(preg_match('#<a id=\'' . $dirname . '\' .*</td><td.*>(.*)</td><td>.*</td><td>.*</td></tr>#', $this->oomph_index_html, $matches)) {
        return $matches[1];
      }
    }
  }
}
