<?php
/**
 * @file
 * Install for a tripal data entity - creates the base table for our entity.
 */

function tripal_entities_install() {

  // add any external databases used by the file module.
  //  tripal_entities_add_dbs();

  // add any controlled vocabularies used by the file module.
  //  tripal_entities_add_cvs();

  // add any controlled vocabulary terms
  //  tripal_entities_add_cvterms();

  // add any custom tables. For this case we will add an 'file' table to the
  // chado schema
  tripal_entities_add_custom_tables();

}

/**
 *
 */
function tripal_entities_add_custom_tables() {
  tripal_entities_add_tripal_vocabulary_table();
  tripal_entities_add_tripal_vocabulary_usage_table();
  tripal_entities_add_tripal_term_table();
  tripal_entities_add_tripal_term_usage_table();
  tripal_entities_add_tripal_term_relationship_table();
}

/**The current Entity Example (Genes) requires the Sequence Ontology.                                     [warning]

 *
 */
function tripal_entities_add_tripal_vocabulary_table() {
  $schema = array (
    'table' => 'tripal_vocabulary',
    'fields' => array (
      'vocabulary_id' => array(
        'type' => 'serial',
        'not null' => TRUE
      ),
      'cv_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'db_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'publish' => array (
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0
      ),
    ),
    'primary key' => array (
      0 => 'vocabulary_id'
    ),
    'foreign keys' => array (
      'cv' => array (
        'table' => 'cv',
        'columns' => array (
          'cv_id' => 'cv_id'
        )
      ),
      'db' => array (
        'table' => 'db',
        'columns' => array (
          'db_id' => 'db_id'
        )
      ),
    ),
    'unique keys' => array (
      'tripal_vocabulary_cvdb' => array (
        'cv_id', 'db_id'
      ),
    ),
    'indexes' => array(
      'tripal_vocabulary_cv_id' => array('cv_id'),
      'tripal_vocabulary_db_id' => array('db_id'),
    )
  );
  chado_create_custom_table('tripal_vocabulary', $schema, TRUE);
}
/**
 *
 */
function tripal_entities_add_tripal_term_table() {
  $schema = array (
    'table' => 'tripal_term',
    'fields' => array (
      'term_id' => array(
        'type' => 'serial',
        'not null' => TRUE
      ),
      'vocabulary_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'cvterm_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'publish' => array (
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0
      ),
    ),
    'primary key' => array (
      0 => 'term_id'
    ),
    'foreign keys' => array (
      'cvterm' => array (
        'table' => 'cvterm',
        'columns' => array (
          'cvterm_id' => 'cvterm_id'
        )
      ),
      'tripal_vocabulary' => array (
        'table' => 'tripal_vocabulary',
        'columns' => array (
          'vocabulary_id' => 'vocabulary_id'
        )
      ),
    ),
    'unique keys' => array (
      'tripal_term_unq' => array (
        'vocabulary_id', 'cvterm_id'
      ),
    ),
    'indexes' => array(
      'tripal_term_vocabulary_id' => array('vocabulary_id'),
      'tripal_term_cvterm_id' => array('cvterm_id'),
    ),
  );
  chado_create_custom_table('tripal_term', $schema, TRUE);
}
/**
 *
 */
function tripal_entities_add_tripal_vocabulary_usage_table(){
  $schema = array (
    'table' => 'tripal_vocabulary_usage',
    'fields' => array (
      'vocabulary_usage_id' => array(
        'type' => 'serial',
        'not null' => TRUE
      ),
      'vocabulary_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'data_table' => array (
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE
      ),
      'type_table' => array (
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE
      ),
      'field' => array (
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE
      ),
    ),
    'primary key' => array (
      0 => 'vocabulary_usage_id'
    ),
    'foreign keys' => array (
      'tripal_vocabulary' => array (
        'table' => 'tripal_vocabulary',
        'columns' => array (
          'vocabulary_id' => 'vocabulary_id'
        ),
      ),
    ),
    'unique keys' => array (
      'tripal_vocabulary_ridbase' => array (
        'vocabulary_id', 'data_table'
      ),
    ),
    'indexes' => array(
      'tripal_vocabulary_vocabulary_id' => array('vocabulary_id'),
      'tripal_vocabulary_data_table' => array('data_table'),
      'tripal_vocabulary_type_table' => array('type_table'),
    ),
  );
  chado_create_custom_table('tripal_vocabulary_usage', $schema, TRUE);
}
/**
 *
 */
function tripal_entities_add_tripal_term_usage_table(){
  $schema = array (
    'table' => 'tripal_term_usage',
    'fields' => array (
      'term_usage_id' => array(
        'type' => 'serial',
        'not null' => TRUE
      ),
      'term_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'data_table' => array (
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE
      ),
      'type_table' => array (
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE
      ),
      'field' => array (
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE
      ),
    ),
    'primary key' => array (
      0 => 'term_usage_id'
    ),
    'foreign keys' => array (
      'tripal_term' => array (
        'table' => 'tripal_term',
        'columns' => array (
          'term_id' => 'term_id'
        ),
      ),
    ),
    'unique keys' => array (
      'tripal_term_usage_ridbase' => array (
        'term_id', 'type_table', 'field'
      ),
    ),
    'indexes' => array(
      'tripal_term_usage_term_id' => array('term_id'),
    ),
  );
  chado_create_custom_table('tripal_term_usage', $schema, TRUE);
}
/**
 *
 */
function tripal_entities_add_tripal_term_relationship_table(){
  $schema = array (
    'table' => 'tripal_term_relationship',
    'fields' => array (
      'relationship_id' => array(
        'type' => 'serial',
        'not null' => TRUE
      ),
      'subject_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'type_id' => array (
        'type' => 'int',
        'not null' => TRUE
      ),
      'object_id' => array (
        'type' => 'int',
        'not null' => FALSE
      ),
      'fieldname' => array(
        'type' => 'varchar',
        'length' => 128,
        'not null' => FALSE,
      )
    ),
    'primary key' => array (
      0 => 'relationship_id'
    ),
    'foreign keys' => array (
      'tripal_term' => array (
        'table' => 'tripal_term',
        'columns' => array (
          'subject_id' => 'term_id',
          'object_id'  => 'term_id',
        ),
      ),
    ),
    'unique keys' => array (
      'tripal_term_relationship_unq' => array (
        'subject_id', 'type_id', 'object_id'
      ),
    ),
    'indexes' => array(
      'tripal_term_relationship_subject_id' => array('subject_id'),
      'tripal_term_relationship_object_id' => array('object_id'),
      'tripal_term_relationship_type_id' => array('type_id'),
    ),
  );
  chado_create_custom_table('tripal_term_relationship', $schema, TRUE);
}
/**
 * Implements hook_schema().
 *
 * @ingroup entity_example
 */
function tripal_entities_schema() {

  $schema['tripal_entity'] = array(
    'description' => 'The base table for Tripal Vocabulary-based entities.',
    'fields' => array(
      'id' => array(
        'description' => 'The primary identifier for a vocabulary entity.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'type' => array(
        'description' => 'The type of entity. This should be an official vocabulary ID (e.g. SO, RO, GO).',
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'default' => '',
      ),
      'bundle' => array(
        'description' => 'The type of bundle. This should be an official vocabulary ID (e.g. SO, RO, GO) followed by an underscore and the term accession.',
        'type' => 'varchar',
        'length' => 1024,
        'not null' => TRUE,
        'default' => '',
      ),
      'cvterm_id' => array(
        'description' => 'The cvterm_id for the type of entity. This cvterm_id should match a record in the Chado cvterm table.',
        'type' => 'int',
        'not null' => TRUE,
      ),
      'title' => array(
        'description' => 'The title of this node, always treated as non-markup plain text.',
        'type' => 'text',
        'not null' => TRUE,
        'default' => '',
      ),
      'uid' => array(
        'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'description' => 'Boolean indicating whether the node is published (visible to non-administrators).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the node was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the node was most recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'cvterm_id' => array('cvterm_id'),
      'entity_changed' => array('changed'),
      'entity_created' => array('created'),
      'type' => array('type'),
      'uid' => array('uid'),
    ),
    'unique keys' => array(
    ),
    'primary key' => array('id'),
  );

  $schema['tripal_bundle'] = array(
    'description' => 'Stores information about defined tripal data types.',
    'fields' => array(
      'id' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique Chado data type identifier.',
      ),
      'type' => array(
        'description' => 'The type of entity. This should be an official vocabulary ID (e.g. SO, RO, GO).',
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'default' => '',
      ),
      'bundle' => array(
        'description' => 'The type of bundle. This should be an official vocabulary ID (e.g. SO, RO, GO) followed by an underscore and the term accession.',
        'type' => 'varchar',
        'length' => 1024,
        'not null' => TRUE,
        'default' => '',
      ),
      'label' => array(
        'description' => 'The human-readable name of this bundle.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'The weight of this tripal data type in relation to others.',
      ),
      'data' => array(
        'type' => 'text',
        'not null' => FALSE,
        'size' => 'big',
        'serialize' => TRUE,
        'description' => 'A serialized array of additional data related to this tripal data type.',
      ),
    ) + entity_exportable_schema_fields(),
    'primary key' => array('id'),
    'unique keys' => array(
      'bundle' => array('bundle'),
    ),
  );

  $schema['chado_entity'] = array(
    'description' => 'The linker table that associates an enitity from the public.tripal_entity table with a "base" record in Chado',
    'fields' => array(
      'chado_entity_id' => array(
        'description' => 'The primary identifier for this table.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'entity_id' => array(
        'description' => 'The unique entity id.',
        'type' => 'int',
        'not null' => TRUE,
      ),
      'record_id' => array(
        'description' => 'The unique numerical identifier for the record that this entity is associated with (e.g. feature_id, stock_id, library_id, etc.).',
        'type' => 'int',
        'not null' => TRUE,
      ),
      'data_table' => array(
        'description' => 'Indicates the table in Chado that this term services (e.g. feature, stock, library, etc.)',
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
        'default' => '',
      ),
      'type_table' => array(
        'description' => 'Sometimes the record in the data table doesn’t have a field that specifies  the record type.  For example, an analysis type is stored in the analysisprop table.  If the data_table does have a type field then this value will be the same as the data_table.',
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
        'default' => '',
      ),
      'field' => array(
        'description' => 'The name of the field in the typetable that contains the cvterm record.',
        'type' => 'varchar',
        'length' => 128,
        'not null' => FALSE,
        'default' => ''
      ),
    ),
    'indexes' => array(
      'record_id' => array('record_id'),
      'entity_id' => array('entity_id'),
      'data_table' => array('data_table'),
    ),
    'unique keys' => array(
      'record' => array('data_table', 'record_id'),
      'entity_id' => array('entity_id'),
    ),
    'primary key' => array('chado_entity_id'),
  );
  return $schema;
}

/**
 * Implements hook_uninstall().
 *
 * At uninstall time we'll notify field.module that the entity was deleted
 * so that attached fields can be cleaned up.
 */
function tripal_entities_uninstall() {
  // TODO: make this dynamic (not hardcoded bundle).
  $terms = chado_generate_var('tripal_term', array('publish' => 1), array('return_array' => 1));

  foreach ($terms as $term) {
    $entity_type = $term->vocab_id->db_id->name;
    $bundle_id = $term->cvterm_id->dbxref_id->db_id->name . '_' . $term->cvterm_id->dbxref_id->accession;
    print "$entity_type : $bundle_id\n";
    field_attach_delete_bundle($entity_type, $bundle_id);
  }
}