<?php
/**
 * *****************************************************************************
 * Copyright (c) 2013, 2014 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
 * *****************************************************************************
 */

class BugzillaClient {
  var $host;
  var $cookieFile;
  var $loggedIn = false;

  /**
   * This is the pattern that we look for to verify that the
   * attempt to login as succeeded.
   * Since we're parsing web pages,
   * we look for an occurance of "Log out" (assuming that we can
   * only log out if we have previously logged in).
   *
   * @var string
   */
  var $loggedInPattern = '/<a href="index.cgi\?logout=1">Log(&nbsp;| )out<\/a>/';
  var $bugCreatedPattern = '/(\d+)+ Submitted/';
  var $attachmentCreatedPattern = '/Attachment (\d+) added/';

  function __construct($host) {
    $this->host = $host;
    $this->cookieFile = tempnam(sys_get_temp_dir(), 'bugzilla');
    if (!$this->cookieFile)
      throw new Exception("The BugzillaClient cannot allocate a cookie file. Check temp directory settings.");
  }

  function isLoggedIn() {
    return $this->loggedIn;
  }

  function login($user, $password) {
    if ($this->isLoggedIn())
      return;

    $query = new BugzillaPostQuery($this, "index.cgi");
    $result = $query->setData('Bugzilla_login', $user)->setData('Bugzilla_password', $password)->setData('GoAheadAndLogIn', 'Login')->execute();

    /*
     * If the value that we get back from the server contains the
     * "loggedInPattern", then we were successful. Otherwise, obviously,
     * we were not successful. In this event, extract the error message
     * from the title and pass it back as the message in an exception.
     */
    if (!preg_match($this->loggedInPattern, $result->contents)) {
      if (preg_match('/<title>(.*)<\/title>/', $result->contents, $matches)) {
        $message = $matches[1];
      }
      else
        $message = 'Unknown error';
      throw new BugzillaInvalidCredentialsException($message);
    }

    $this->loggedIn = true;

    return $this;
  }

  function logout() {
    // TODO Should we throw an exception?
    if (!$this->isLoggedIn())
      return;

    $query = new BugzillaPostQuery($this, "index.cgi");
    $query->setData('logout', '1')->execute();

    $this->loggedIn = false;
  }

  /**
   *
   * @param string $product
   * @param string $component
   * @param string $summary
   * @return BugBuilder
   */
  function startBug($product, $component, $summary) {
    return new BugBuilder($this, $product, $component, $summary);
  }

  function findBugs() {
    return new BugFinder($this);
  }

  /**
   * Answers a representation of the bug.
   * Note that no check is done
   * to ensure that this bug actually exists.
   *
   * @param int $id
   *        The bug id.
   * @return Bug
   */
  function getBug($id) {
    return new Bug($this, $id);
  }

}

class BugzillaInvalidCredentialsException extends Exception {

}

/**
 * Instances of BugBuilder are used--oddly enough--to build bugs.
 * You
 * should never directly create an instance of this class. Instead, send
 * the startAttachment() message to a Bug instance.
 *
 * All of the methods implemented by this class return the receiver.
 * This lets you chain multiple calls against the instance using relatively
 * compact and easy-to-read code (that's the intention, anyway).
 *
 * The final message sent is generally create() which does the actual work
 * based on the information that's been provided.
 *
 * @internal
 *
 * @see Bug::startAttachment
 */
class BugBuilder {
  var $client;
  var $product;
  var $component;
  var $summary;
  var $body = array();
  var $keywords = array();
  var $assignee;
  var $cc = array();
  var $operatingSystem = 'All';
  var $platform = 'All';
  var $severity = 'normal';
  var $priority = 'P3';
  var $version = 'unspecified';
  var $url;
  var $otherFields = array();

  function __construct($client, $product, $component, $summary) {
    $this->client = $client;
    $this->product = $product;
    $this->component = $component;
    $this->summary = $summary;
  }

  /**
   * Add a paragraph to comment #0 of the new bug.
   * Each paragraph
   * is separated from the previous paragraph by a blank line.
   * The second (optional) parameter is a boolean value, the paragraph
   * is only added if that parameter's value is true. This provides
   * a relatively convenient way to build up the content without
   * having to include a whole bunch of if statements to chop up
   * an otherwise very tidy code flow.
   *
   * Like every other method on this class, the return value is the
   * receiver, so that additional messages can be sent.
   *
   * @param string $paragraph
   * @param boolean $include
   * @return AttachmentBuilder
   */
  function addParagraph($paragraph, $include = true) {
    if ($include)
      $this->body[] = $paragraph;
    return $this;
  }

  function addKeyword($keyword) {
    $this->keywords[] = $keyword;
    return $this;
  }

  function setAssignee($email) {
    $this->assignee = $email;
    return $this;
  }

  function addCC($email) {
    $this->cc[] = $email;
    return $this;
  }

  function setOperatingSystem($os) {
    $this->operatingSystem = $os;
    return $this;
  }

  function setPlatform($platform) {
    $this->platform = $platform;
    return $this;
  }

  function setSeverity($severity) {
    $this->severity = $severity;
    return $this;
  }

  function setPriority($priority) {
    $this->priority = $priority;
    return $this;
  }

  function setVersion($version) {
    $this->version = $version;
    return $this;
  }

  function setUrl($url) {
    $this->url = $url;
    return $this;
  }

  function set($field, $value) {
    $this->otherFields[$field] = $value;
    return $this;
  }

  function create() {
    // Recent versions of Bugzilla require a token when creating
    // a bug. Attempt to get the token.
    // FIXME Only do this if the Bugzilla version requires it.
    $query = new BugzillaGetQuery($this->client, 'enter_bug.cgi');
    $queryFormResult = $query->setData('product', $this->product)->setData('component', $this->component)->execute();

    $query = new BugzillaPostQuery($this->client, 'post_bug.cgi');
    $query->setData('form_name', 'enter_bug')->setData('token', $queryFormResult->getToken())->setData('product', $this->product)->setData('component', $this->component)->setData('assigned_to', $this->assignee)->setData('cc', join(',', $this->cc))->setData('short_desc', $this->summary)->setData('comment', join("\n\n", $this->body))->setData('op_sys', $this->operatingSystem)->setData('rep_platform', $this->platform)->setData('bug_severity', $this->severity)->setData('priority', $this->priority)->setData('version', $this->version)->setData('keywords', join(',', $this->keywords))->setData('bug_file_loc', $this->url);

    foreach ($this->otherFields as $key => $value) {
      $query->setData($key, $value);
    }

    $result = $query->execute();

    if (preg_match($this->client->bugCreatedPattern, $result->contents, $matches)) {
      return new Bug($this->client, $matches[1]);
    }

    if (preg_match('/<title>(.*)<\/title>/ims', $result->contents, $matches)) {
      $message = preg_replace('/\s+/', ' ', $matches[1]);
    }
    else
      $message = 'Unknown error';

      // TODO Make custom exception
    throw new Exception($message);
  }

  /**
   * Answer a URL that will open a browser with a pre-populated
   * create page.
   */
  function getUrl() {
    $parameters = array(
      'product' => $this->product,
      'component' => $this->component,
      'assigned_to' => $this->assignee,
      'cc' => join(',', $this->cc),
      'short_desc' => $this->summary,
      'comment' => join("\n\n", $this->body),
      'op_sys' => $this->operatingSystem,
      'rep_platform' => $this->platform,
      'bug_severity' => $this->severity,
      'priority' => $this->priority,
      'version' => $this->version,
      'keywords' => join(',', $this->keywords),
      'bug_file_loc' => $this->url
    );

    $url = $this->client->host . '/enter_bug.cgi?';
    foreach ($parameters as $key => $value) {
      if ($value)
        $url .= "$key=" . urlencode($value) . '&';
    }
    return $url;
  }

}

class BugFinder {
  var $client;
  var $parameters = array(
    'columnlist' => array(
      'bug_id'
    )
  );

  function __construct(BugzillaClient $client) {
    $this->client = $client;
  }

  function setProduct($product) {
    $this->parameters['product'] = array(
      $product
    );
    return $this;
  }

  function setComponent($component) {
    $this->parameters['component'] = array(
      $component
    );
    return $this;
  }

  function addColumn($column) {
    $this->parameters['columnlist'][] = $column;
    return $this;
  }

  function setSummary($summary) {
    $this->parameters['short_desc'] = array(
      $summary
    );
    $this->parameters['short_desc_type'] = array(
      'substring'
    );
    return $this;
  }

  function addKeyword($keyword) {
    $this->parameters['keywords'][] = $keyword;
    return $this;
  }

  function addStatus($status) {
    $this->parameters['bug_status'][] = $status;
    return $this;
  }

  /**
   * Execute the search.
   * The returned value is an array of
   * arrays.
   *
   * e.g. array(array('bug_id' => 1234, 'short_desc' => 'Something', ...), ...)
   *
   * @see searchBugs
   * @return mixed[][]
   */
  function search() {
    $query = new BugzillaGetQuery($this->client, 'buglist.cgi');
    foreach ($this->parameters as $key => $values) {
      $query->setData($key, join(',', $values));
    }

    $result = $query->setData('ctype', 'csv')->execute();
    return $result->getCsv();
  }

  /**
   * Execute the search but return a collection of instances of the
   * bug class.
   *
   * @return Bug[]
   */
  function searchBugs() {
    $bugs = array();
    foreach ($this->search() as $row) {
      $bugs[] = new Bug($this->client, $row['bug_id']);
    }
    return $bugs;
  }

}

/**
 * Instances of AttachmentBuilder are used--oddly enough--to build attachments.
 * You
 * should never directly create an instance of this class. Instead, send
 * the startBug() message to a BugzillaClient instance.
 *
 * All of the methods implemented by this class return the receiver.
 * This lets you chain multiple calls against the instance using relatively
 * compact and easy-to-read code (that's the intention, anyway).
 *
 * The final message sent is generally create() which does the actual work
 * based on the information that's been provided.
 *
 * @internal
 *
 * @see BugzillaClient::startBug
 */
class AttachmentBuilder {
  var $bug;
  var $file;
  var $description = 'A file';
  var $body = array();

  function __construct($bug) {
    $this->bug = $bug;
  }

  function setFile($file) {
    $this->file = $file;
    return $this;
  }

  function setDescription($description) {
    $this->description = $description;
    return $this;
  }

  /**
   * Add a paragraph to the comment for the attachment.
   * Each paragraph
   * is separated from the previous paragraph by a blank line.
   * The second (optional) parameter is a boolean value, the paragraph
   * is only added if that parameter's value is true. This provides
   * a relatively convenient way to build up the content without
   * having to include a whole bunch of if statements to chop up
   * an otherwise very tidy code flow.
   *
   * Like every other method on this class, the return value is the
   * receiver, so that additional messages can be sent.
   *
   * @param string $paragraph
   * @param boolean $include
   * @return AttachmentBuilder
   */
  function addParagraph($paragraph, $include = true) {
    if ($include)
      $this->body[] = $paragraph;
    return $this;
  }

  function create() {
    $query = new BugzillaGetQuery($this->bug->client, 'attachment.cgi');
    $queryFormResult = $query->setData('bugid', $this->bug->id)->setData('action', 'enter')->execute();

    $query = new BugzillaPostQuery($this->bug->client, 'attachment.cgi');
    $result = $query->setData('form_name', 'enter_bug')->setData('token', $queryFormResult->getToken())->setData('bugid', $this->bug->id)->setData('action', 'insert')->setData('data', "@$this->file")->setData('description', $this->description)->setData('comment', join("\n\n", $this->body))->setData('contenttypemethod', 'list')->setData('contenttypeselection', 'text/html')->execute();

    if (preg_match($this->bug->client->attachmentCreatedPattern, $result->contents, $matches)) {
      return new Attachment($this->bug, $matches[1]);
    }

    if (preg_match('/<title>(.*)<\/title>/ims', $result->contents, $matches)) {
      $message = preg_replace('/\s+/', ' ', $matches[1]);
    }
    else
      $message = 'Unknown error';

      // TODO Make custom exception
    throw new Exception($message);
  }

}

/**
 * Instances of this class represent a bug instance from the client.
 * Instances
 * should not be directly created, but should instead be created by sending
 * a message to an instance of the BugzillaClient class.
 *
 * @internal
 *
 * @see BugzillaClient::getBug
 * @see BugzillaClient::startBug
 */
class Bug {
  var $client;
  var $id;

  function __construct($client, $id) {
    $this->client = $client;
    $this->id = $id;
  }

  function getId() {
    return $this->id;
  }

  function startAttachment() {
    return new AttachmentBuilder($this);
  }

  function getUrl() {
    return $this->client->host . '/show_bug.cgi?id=' . $this->id;
  }

}

/**
 * Instances of this class represent an attachment instance from the client.
 * Instances should not be directly created, but should instead be created by
 * sending a message to an instance of the Bug class.
 *
 * @internal
 *
 * @see Bug::startAttachment
 */
class Attachment {
  var $bug;
  var $id;

  function __construct($bug, $id) {
    $this->bug = $bug;
    $this->id = $id;
  }

}

/**
 * Instances of this class are used to build and execute a POST query
 * against Bugzilla.
 *
 * @internal
 *
 */
class BugzillaPostQuery {
  var $client;
  var $resource;
  var $parameters = array();

  function __construct($client, $resource) {
    $this->client = $client;
    $this->resource = $resource;
  }

  function setData($key, $value) {
    $this->parameters[$key] = $value;
    return $this;
  }

  function getUrl() {
    return $this->client->host . '/' . $this->resource;
  }

  function getDefaultOptions() {
    return array(
      CURLOPT_USERAGENT => "Eclipse",
      CURLOPT_COOKIEFILE => $this->client->cookieFile,
      CURLOPT_COOKIEJAR => $this->client->cookieFile,
      // CURLOPT_VERBOSE => 1,
      // CURLOPT_FOLLOWLOCATION => true,
      CURLOPT_RETURNTRANSFER => 1,
      CURLOPT_URL => $this->getUrl()
    );
  }

  function getOptions() {
    $options = $this->getDefaultOptions();
    $options[CURLOPT_POST] = TRUE;
    $options[CURLOPT_POSTFIELDS] = $this->parameters;
    return $options;
  }

  function execute() {
    $curl = curl_init($this->client->host);
    curl_setopt_array($curl, $this->getOptions());
    $contents = curl_exec($curl);
    curl_close($curl);
    return new QueryResult($contents);
  }

}

class QueryResult {
  var $contents;

  function __construct($contents) {
    $this->contents = $contents;
  }

  function getToken() {
    if (preg_match('/<input type="hidden" name="token" value="(\w+)">/', $this->contents, $matches))
      return $matches[1];
    return null;
  }

  public function getCsv() {
    // FIXME switch to str_getcsv when we upgrade to PHP 5.3+
    // TODO Make sure that the data is indeed CSV data.

    // We need to support pre-5.3 versions of PHP which do not include
    // the str_getcsv function. Use some string-to-stream cleverness in
    // its place.
    //
    // If fopen fails because, for example, PHP is configured for it
    // to fail (via php.ini), then we brute force it with a regular
    // expression.
    if ($stream = fopen('data://text/plain,' . $this->contents, 'r')) {
      $header = fgetcsv($stream);
      $rows = array();
      while ($values = fgetcsv($stream)) {
        $row = array();
        for ($index = 0; $index < count($header); $index++)
          $row[$header[$index]] = $values[$index];
        $rows[] = $row;
      }
      fclose($stream);
      return $rows;
    }
    else {
      $lines = explode("\n", $this->contents);
      $header = $this->sgetcsv(current($lines));
      $rows = array();
      while ($line = next($lines)) {
        $values = $this->sgetcsv($line);
        $row = array();
        for ($index = 0; $index < count($header); $index++)
          $row[$header[$index]] = $values[$index];
        $rows[] = $row;
      }
      return $rows;
    }
  }

  /**
   * This is a quick and dirty implementation of a string CSV parser.
   * I'm sure that we can come up with a more clever regex, but this
   * one will do.
   *
   * @internal
   *
   * @param unknown $input
   * @return string[]
   */
  private function sgetcsv($input) {
    $values = array();
    if (preg_match_all('/(?:^|,)((?!")[^,|$]*|"(?:[^"\\\\]|\\\\.)*")/', $input, $matches)) {
      foreach ($matches[1] as $match) {
        if (preg_match('/^"(.*)"$/', $match, $contents)) {
          $match = stripslashes($contents[1]);
        }
        $values[] = $match;
      }
    }
    return $values;
  }

}

class BugzillaGetQuery extends BugzillaPostQuery {

  function getUrl() {
    return parent::getUrl() . '?' . $this->getParameters();
  }

  function getOptions() {
    $options = $this->getDefaultOptions();
    $options[CURLOPT_HTTPGET] = TRUE;
    return $options;
  }

  function getParameters() {
    $parameters = array();
    foreach ($this->parameters as $key => $value)
      $parameters[] = "$key=" . urlencode($value);
    return join('&', $parameters);
  }

}