<?php

/**
 * @file
 * Tests for derivative generation.
 */

/**
 * Implements hook_islandora_CMODEL_PID_derivative().
 */
function islandora_derivatives_test_some_cmodel_islandora_derivative() {
  return array(
    array(
      'source_dsid' => 'OBJ',
      'destination_dsid' => 'DERIV',
      'weight' => '0',
      'function' => array(
        'islandora_derivatives_test_create_deriv_datastream',
      ),
    ),
    array(
      'source_dsid' => 'SOMEWEIRDDATASTREAM',
      'destination_dsid' => 'STANLEY',
      'weight' => '-1',
      'function' => array(
        'islandora_derivatives_test_create_stanley_datastream',
      ),
    ),
    array(
      'source_dsid' => NULL,
      'destination_dsid' => 'NOSOURCE',
      'weight' => '-3',
      'function' => array(
        'islandora_derivatives_test_create_nosource_datastream',
      ),
    ),
  );
}

/**
 * Creates the DERIV datastream for use in testing.
 *
 * @param AbstractObject $object
 *   An AbstractObject representing a Fedora object.
 * @param bool $force
 *   Whether or not derivative generation is to be forced.
 * @return array
 *   An array detailing the success of the operation.
 *
 * @see hook_islandora_derivative()
 */
function islandora_derivatives_test_create_deriv_datastream(AbstractObject $object, $force = FALSE) {
  global $_islandora_derivative_test_derivative_functions;
  $_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_deriv_datastream';
  $return = '';
  if (!isset($object['DERIV']) || (isset($object['DERIV']) && $force === TRUE)) {
    if ($force !== TRUE || !isset($object['DERIV'])) {
      $deriv_string = $object['OBJ']->content . ' some string';
    }
    else {
      $deriv_string = "FORCEFULLY APPENDING CONTENT TO " . $object['OBJ']->content;
    }
    $added_successfully = islandora_derivatives_test_add_datastream($object, 'DERIV', $deriv_string);
    if ($added_successfully !== TRUE) {
      $return = islandora_derivatives_test_failed_adding($added_successfully);
    }
    else {
      $return = array(
        'success' => TRUE,
        'messages' => array(
          array(
            'message' => t('The DERIV datastream was added successfully for @pid!'),
            'message_sub' => array('@pid' => $object->id),
            'type' => 'dsm',
          ),
        ),
      );
    }
    return $return;
  }
}

/**
 * Creates the STANLEY datastream for use in testing.
 *
 * @param AbstractObject $object
 *   An AbstractObject representing a Fedora object.
 * @param bool $force
 *   Whether the derivatives are being forcefully generated or not.
 */
function islandora_derivatives_test_create_stanley_datastream(AbstractObject $object, $force = FALSE) {
  global $_islandora_derivative_test_derivative_functions;
  // Add to the global that we got to this function.
  $_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_some_weird_datastream';
  if (!isset($object['STANLEY']) || (isset($object['STANLEY']) && $force === TRUE)) {
    islandora_derivatives_test_add_datastream($object, 'STANLEY', 'yum');
  }
}

/**
 * Creates the NOSOURCE datastream for use in testing.
 *
 * @param AbstractObject $object
 *   An AbstractObject representing a Fedora object.
 * @param bool $force
 *   Whether or not derivative generation is to be forced.
 * @return array
 *   An array detailing the success of the operation.
 *
 * @see hook_islandora_derivative()
 */
function islandora_derivatives_test_create_nosource_datastream(AbstractObject $object, $force = FALSE) {
  global $_islandora_derivative_test_derivative_functions;
  $_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_nosource_datastream';
  $return = '';
  if (!isset($object['NOSOURCE']) || (isset($object['NOSOURCE']) && $force === TRUE)) {
    if ($force !== TRUE || !isset($object['NOSOURCE'])) {
      $deriv_string = 'NOSOURCE';
    }
    else {
      $deriv_string = "FORCEFULLY APPENDING CONTENT TO " . $object['NOSOURCE']->content;
    }
    $added_successfully = islandora_derivatives_test_add_datastream($object, 'NOSOURCE', $deriv_string);
    if ($added_successfully !== TRUE) {
      $return = islandora_derivatives_test_failed_adding($added_successfully);
    }
    else {
      $return = array(
        'success' => TRUE,
        'messages' => array(
          array(
            'message' => t('The DERIV datastream was added successfully for @pid!'),
            'message_sub' => array('@pid' => $object->id),
            'type' => 'dsm',
          ),
        ),
      );
    }
    return $return;
  }
}

/**
 * Helper function that adds/modifies the datastream to the object in testing.
 *
 * @param AbstractObject $object
 *   An AbstractObject representing a Fedora object.
 * @param string $dsid
 *   The datastream id for which we are adding/modifying.
 * @param string $deriv_string
 *   The content of the datastream we are adding.
 *
 * @return bool|string
 *   A bool if the operation was successfully, the error message otherwise.
 */
function islandora_derivatives_test_add_datastream(AbstractObject $object, $dsid, $deriv_string) {
  global $_islandora_derivative_test_ingest_method;
  try {
    $ingest = !isset($object[$dsid]);
    if ($ingest) {
      $ds = $object->constructDatastream($dsid, 'M');
      $ds->label = $dsid;
    }
    else {
      $ds = $object[$dsid];
    }
    $ds->content = $deriv_string;
    if ($ingest) {
      $_islandora_derivative_test_ingest_method = 'ingestDatastream';
      $object->ingestDatastream($ds);
    }
    else {
      $_islandora_derivative_test_ingest_method = 'modifyDatastream';
    }
    return TRUE;
  }
  catch (exception $e) {
    $message = $e->getMessage();
    return $message;
  }
}

/**
 * Returns a message if we failed to add a derivative.
 *
 * @see hook_islandora_derivative()
 *
 * @param string $message
 *   The error message to be returned back.
 *
 * @return array
 *   An array describing the outcome of our failure.
 */
function islandora_derivatives_test_failed_adding($message) {
  return array(
    'success' => FALSE,
    'messages' => array(
      array(
        'message' => $message,
        'type' => 'watchdog',
        'severity' => WATCHDOG_ERROR,
      ),
    ),
  );
}