<?php

/**
 * Implementation of hook_install(). 
 */
function eolapi_enable(){
  $field = field_info_field('eolapi_taxonomy');
  if($field){
    field_delete_field('eolapi_taxonomy');
  }
  $field = field_info_field('eolapi_image');
  if($field){
    field_delete_field('eolapi_image');
  }
  // Create a new field and field instance, and connect it with all the eolapi
  // bundles.
  $field = array(
    'active' => '1',
    'cardinality' => '1',
    'deleted' => '0',
    'entity_types' => array(
      'eolapi'
    ),
    'field_name' => 'eolapi_taxonomy',
    'foreign keys' => array(
      'tid' => array(
        'columns' => array(
          'tid' => 'tid'
        ),
        'table' => 'taxonomy_term_data'
      )
    ),
    'indexes' => array(
      'tid' => array(
        0 => 'tid'
      )
    ),
    'module' => 'taxonomy',
    'settings' => array(
      'allowed_values' => array(
        '0' => array(
          'parent' => 0,
          'vocabulary' => 'tags'
        )
      )
    ),
    'translatable' => '0',
    'type' => 'taxonomy_term_reference'
  );
  $bio_vids = variable_get('biological_vids', array());
  $i = 0;
  foreach($bio_vids as $vid => $value){
    $vocabulary = taxonomy_vocabulary_load($vid);
    if($vocabulary){
      $field['settings']['allowed_values'][$i] = array(
        'parent' => 0,
        'vocabulary' => $vocabulary->machine_name
      );
    }
    $i++;
  }
  $instance = array(
    'bundle' => '',
    'default_value' => NULL,
    'deleted' => '0',
    'description' => '',
    'display' => array(
      'default' => array(
        'label' => 'above',
        'module' => 'taxonomy',
        'settings' => array(
          'allowed_values' => array(
            'parent' => 0,
            'vocabulary' => ''
          )
        ),
        'type' => 'taxonomy_term_reference_link',
        'weight' => 1
      ),
      'teaser' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'hidden',
        'weight' => 0
      )
    ),
    'entity_type' => 'eolapi',
    'field_name' => 'eolapi_taxonomy',
    'label' => 'Taxonomy field',
    'required' => 0, // FIXME - Should this be required?
    'settings' => array(),
    'widget' => array(
      'active' => 0,
      'module' => 'taxonomy',
      'settings' => array(
        'autocomplete_path' => 'taxonomy/autocomplete',
        'size' => 60
      ),
      'type' => 'taxonomy_autocomplete',
      'weight' => '-3'
    )
  );
  field_create_field($field);
  $eolapi_entity_info = eolapi_entity_info();
  foreach($eolapi_entity_info['eolapi']['bundles'] as $bundle => $bundle_info){
    $instance['bundle'] = $bundle;
    field_create_instance($instance);
  }
  // Create an image field to be associated with the stillimage bundle.
  $field = array(
    'active' => '1',
    'cardinality' => '1',
    'deleted' => '0',
    'entity_types' => array(
      'eolapi'
    ),
    'field_name' => 'eolapi_image',
    'foreign keys' => array(
      'fid' => array(
        'columns' => array(
          'fid' => 'fid'
        ),
        'table' => 'file_managed'
      )
    ),
    'indexes' => array(
      'fid' => array(
        0 => 'fid'
      )
    ),
    'module' => 'image',
    'settings' => array(
      'default_image' => FALSE,
      'uri_scheme' => 'public'
    ),
    'translatable' => '0',
    'type' => 'image'
  );
  $instance = array(
    'bundle' => 'stillimage',
    'deleted' => '0',
    'description' => 'Upload an image to go with this article.',
    'display' => array(
      'default' => array(
        'label' => 'hidden',
        'module' => 'image',
        'settings' => array(
          'image_link' => '',
          'image_style' => 'large'
        ),
        'type' => 'image',
        'weight' => -1
      ),
      'teaser' => array(
        'label' => 'hidden',
        'module' => 'image',
        'settings' => array(
          'image_link' => 'content',
          'image_style' => 'medium'
        ),
        'type' => 'image',
        'weight' => -1
      )
    ),
    'entity_type' => 'eolapi',
    'field_name' => 'eolapi_image',
    'label' => 'Image',
    'required' => FALSE,
    'settings' => array(
      'alt_field' => TRUE,
      'file_directory' => 'field/image',
      'file_extensions' => 'png gif jpg jpeg',
      'max_filesize' => '',
      'max_resolution' => '',
      'min_resolution' => '',
      'title_field' => '',
      'user_register_form' => FALSE
    ),
    'widget' => array(
      'module' => 'image',
      'settings' => array(
        'preview_image_style' => 'thumbnail',
        'progress_indicator' => 'throbber'
      ),
      'type' => 'image_image',
      'weight' => -1
    )
  );
  field_create_field($field);
  field_create_instance($instance);
}

/**
 * Implementation of hook_uninstall().
 */
function eolapi_disable(){
  field_delete_field('eolapi_taxonomy');
  field_delete_field('eolapi_image');
  // Delete all the eolapi entities.
  $results = db_select('eolapi', 'e')->fields('e', array(
    'eid'
  ))->execute();
  $ids = array();
  foreach($results as $row){
    $ids[] = $row->eid;
  }
  if(count($ids)){
    entity_delete_multiple('eolapi', $ids);
  }
  // Delete all the files that were associated with those entities.
  db_delete('file_usage')->condition('type', 'eolapi')->execute();
  //   // We do it this way round, as this will catch all eolapi files, and not just
  //   // those that still have entries in the file_usage table (which I would expect
  //   // to be emptied after the entity is deleted).
  //   $results = db_select('file_managed', 'f')->fields('f', array(
  //     'fid'
  //   ))->condition('uri', db_like('public://eolapi/') . '%', 'LIKE')->execute();
  //   $fids = array();
  //   foreach($results as $row){
  //     $fids[] = $row->fid;
  //   }
  //   $files = file_load_multiple($fids);
  //   foreach($files as $file){
  //     file_delete($file);
  //   }
  // FIXME - We need to delete the EOLAPI files.
}

/**
 * Implementation of hook_schema().
 */
function eolapi_schema(){
  return array(
    'eolapi' => array(
      'fields' => array(
        'eid' => array(
          'description' => 'Primary key',
          'type' => 'serial',
          'unsigned' => TRUE,
          'not null' => TRUE
        ),
        'erid' => array(
          'description' => 'Revision key',
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
          'default' => 0
        ),
        'data' => array(
          'description' => 'Serialized PHP data',
          'type' => 'text',
          'size' => 'big',
          'not null' => TRUE
        ),
        'type' => array(
          'description' => 'The type of this EOL data item.',
          'type' => 'varchar',
          'length' => 32,
          'not null' => TRUE,
          'default' => ''
        ),
        'label' => array(
          'description' => 'The label of this EOL data item.',
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
          'default' => ''
        ),
        'trusted' => array(
          'description' => 'The "vettedStatus" of this item of data.  Note, this is not used by the search and pages bundles.',
          'type' => 'int',
          'size' => 'tiny',
          'not null' => TRUE,
          'default' => 0
        ),
        'license' => array(
          'description' => 'The type of this EOL data item.  Note, this is not used by the search and pages bundles.',
          'type' => 'varchar',
          'length' => 256,
          'not null' => TRUE,
          'default' => ''
        ),
        'rating' => array(
          'description' => 'The "dataRating" of this item of data.  Note, this is not used by the search and pages bundles.',
          'type' => 'float',
          'size' => 'small',
          'not null' => TRUE,
          'default' => 0
        ),
        'created' => array(
          'description' => 'The Unix timestamp when the data item was created.',
          'type' => 'int',
          'not null' => TRUE,
          'default' => 0
        ),
        'changed' => array(
          'description' => 'The Unix timestamp when the data item was most recently updated.',
          'type' => 'int',
          'not null' => TRUE,
          'default' => 0
        ),
        'weight' => array(
          'description' => 'Allow us to order the external content.',
          'type' => 'int',
          'not null' => TRUE,
          'default' => 0
        ),
        'source' => array(
          'description' => 'Used to record the source. E.g. Swiss Orchid Foundation',
          'type' => 'varchar',
          'length' => 256,
          'not null' => TRUE,
          'default' => ''
        )
      ),
      'indexes' => array(
        'eid' => array(
          'eid'
        ),
        'erid' => array(
          'erid'
        ),
        'weight' => array(
          'weight'
        )
      ), // FIXME - Add unique type/label key.
      'primary key' => array(
        'eid'
      )
    ),
    'eolapi_revision' => array(
      'fields' => array(
        'eid' => array(
          'description' => 'Instances of...',
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
          'default' => 0
        ),
        'erid' => array(
          'description' => 'Primary key',
          'type' => 'serial',
          'unsigned' => TRUE,
          'not null' => TRUE
        ),
        'data' => array(
          'description' => 'Serialized PHP data',
          'type' => 'text',
          'size' => 'big',
          'not null' => TRUE
        ),
        'type' => array(
          'description' => 'The type of this EOL data item.',
          'type' => 'varchar',
          'length' => 32,
          'not null' => TRUE,
          'default' => ''
        ),
        'label' => array(
          'description' => 'The label of this EOL data item.',
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
          'default' => ''
        ),
        'trusted' => array(
          'description' => 'The "vettedStatus" of this item of data.  Note, this is not used by the search and pages bundles.',
          'type' => 'int',
          'size' => 'tiny',
          'not null' => TRUE,
          'default' => 0
        ),
        'license' => array(
          'description' => 'The type of this EOL data item.  Note, this is not used by the search and pages bundles.',
          'type' => 'varchar',
          'length' => 256,
          'not null' => TRUE,
          'default' => ''
        ),
        'rating' => array(
          'description' => 'The "dataRating" of this item of data.  Note, this is not used by the search and pages bundles.',
          'type' => 'float',
          'size' => 'small',
          'not null' => TRUE,
          'default' => 0
        ),
        'timestamp' => array(
          'description' => 'A Unix timestamp indicating when this version was created.',
          'type' => 'int',
          'not null' => TRUE,
          'default' => 0
        ),
        'source' => array(
          'description' => 'Used to record the source. E.g. Swiss Orchid Foundation',
          'type' => 'varchar',
          'length' => 256,
          'not null' => TRUE,
          'default' => ''
        )
      ),
      'indexes' => array(
        'eid' => array(
          'eid'
        ),
        'erid' => array(
          'erid'
        ),
        'label' => array(
          'label'
        )
      ),
      'primary key' => array(
        'erid'
      )
    )
  );
}

function eolapi_update_7001(){
  $field_spec = array(
    'description' => 'Used to record the source. E.g. Swiss Orchid Foundation',
    'type' => 'varchar',
    'length' => 256,
    'not null' => TRUE,
    'default' => ''
  );
  db_add_field('eolapi', 'source', $field_spec);
  db_add_field('eolapi_revision', 'source', $field_spec);
  //Set EOL flag on existing eolapi entities
  db_query("UPDATE {eolapi} SET source = 'EOL' WHERE source = ''");
  db_query("UPDATE {eolapi_revision} SET source = 'EOL' WHERE source = ''");
}

/**
 * Prevent access denied for thumbnails. 
 */
function eolapi_update_7002(){
  variable_set('image_allow_insecure_derivatives', TRUE);
}

/**
 * Convert images to be stored remotely.
 */
function eolapi_update_7003(&$sandbox){
  if(empty($sandbox['eids'])){
    // Enable the remote_stream_wrapper module.
    module_enable(array(
      'remote_stream_wrapper'
    ));
    // Delete the eolapi directory
    file_unmanaged_delete_recursive('public://eolapi/');
    // Get the eids to update
    $sandbox['eids'] = db_select('eolapi', 'e')->condition('type', 'stillimage')->fields('e', array(
      'eid'
    ))->execute()->fetchCol();
    $sandbox['total'] = count($sandbox['eids']);
    // Check we have eids to update, if not, we go no further.
    if(!$sandbox['total']){return;}
  }
  $count = 0;
  // Process 50 eids at a time.
  while($count < 50 && ($eid = array_pop($sandbox['eids']))){
    $eolapi = eolapi_load($eid);
    $data = unserialize($eolapi->data);
    if($data && $data->mediaURL){
      $file = file_load($eolapi->eolapi_image[LANGUAGE_NONE][0]['fid']);
      file_unmanaged_delete($file->uri);
      $filename = basename($data->mediaURL);
      try{
        db_update('file_managed')->fields(array(
          'uri' => $data->mediaURL,
          'filename' => $filename,
          'filemime' => 'image/jpeg',
          'type' => 'image'
        ))->condition('fid', $file->fid)->execute();
      }
      catch(Exception $e){
        // We've already got this URL/image, so we delete the EOLAPI entity.
        entity_delete('eolapi', $eid);
      }
    }
    $count++;
  }
  drupal_set_message(($sandbox['total'] - count($sandbox['eids'])) . ' of ' . $sandbox['total']);
  $sandbox['#finished'] = ($sandbox['total'] - count($sandbox['eids'])) / $sandbox['total'];
}

/**
 * Delete any files / eolapi entities that have not been updated.
 */
function eolapi_update_7004(&$sandbox){
  if(empty($sandbox['fids']) && empty($sandbox['eids'])){
    // Get the eids that we need to delete
    $subquery = db_select('file_managed', 'f')->condition('uri', 'public://eolapi/%', 'LIKE')->fields('f', array(
      'fid'
    ));
    $sandbox['eids'] = db_select('field_data_eolapi_image', 'e')->fields('e', array(
      'entity_id'
    ))->condition('eolapi_image_fid', $subquery, 'IN')->fields('e', array(
      'entity_id'
    ))->execute()->fetchCol();
    $sandbox['total'] = count($sandbox['eids']);
    // Check we have eids to update, if not, we go no further.
    if(!$sandbox['total']){return;}
  }
  $count = 0;
  // Process 50 eids at a time.
  $eids = array();
  while($count < 5 && ($eid = array_pop($sandbox['eids']))){
    $eids[] = $eid;
    $count++;
  }
  entity_delete_multiple('eolapi', $eids);
  drupal_set_message(($sandbox['total'] - count($sandbox['eids'])) . ' of ' . $sandbox['total']);
  $sandbox['#finished'] = ($sandbox['total'] - count($sandbox['eids'])) / $sandbox['total'];
}

/**
 * Clear all caches following EOLAPI updates
 */
function eolapi_update_7005(){
  drupal_flush_all_caches();
}

/**
 * Add an index to the label field on the eolapi table.
 */
function eolapi_update_7006(){
  if(!db_index_exists('eolapi', 'label')){
    db_add_index('eolapi', 'label', array(
      'label'
    ));
  }
}