<?php
/**
 * @file
 * Installation of the phylotree module
 */

/**
 * Implements hook_install().
 *
 * @ingroup tripal_phylogeny
 */
function tripal_phylogeny_install() {

  // Add the vocabularies used by the feature module.
  tripal_phylogeny_add_cvterms();

  // Set the default vocabularies.
  tripal_set_default_cv('phylonode', 'type_id', 'tripal_phylogeny');
  tripal_set_default_cv('phylotree', 'type_id', 'sequence');

  // Add the materializedviews.
  tripal_phylogeny_add_mview();

  // We want to integrate the materialized views so that they
  // are available for Drupal Views, upon which our search forms are built.
  tripal_phylogeny_integrate_view();
  $mview_id =  tripal_get_mview_id('phylotree_count');

  // SPF: commented out automatic populate of MView.  If the query fails
  // for some reason the install will not properly complete.
  // tripal_populate_mview($mview_id);

  // Add the custom tables.
  tripal_phylogeny_add_custom_tables();

  // Add an index on the phylonode table.
  $exists = chado_index_exists('phylonode', 'parent_phylonode_id');
  if (!$exists) {
    chado_add_index('phylonode', 'parent_phylonode_id', array('parent_phylonode_id'));
  }

  // Add in the variables that this module will use to store properties for
  // loading of the tree files.
  tripal_insert_variable('phylotree_name_re', 'The regular expression for matching a name in a string.');
  tripal_insert_variable('phylotree_use_uniquename', 'Set to 1 if features should be matched using the unqiuename rather than the name.');
  tripal_insert_variable('phylotree_tree_file', 'Holds the Drupal file ID for the uploaded tree file.');
}

/**
 * Implements hook_disable().
 *
 * Disable default views when module is disabled
 *
 * @ingroup tripal_phylogeny
 */
function tripal_phylogeny_disable() {
  // Disable all default views provided by this module
  require_once("tripal_phylogeny.views_default.inc");
  $views = tripal_phylogeny_views_default_views();
  foreach (array_keys($views) as $view_name) {
    tripal_disable_view($view_name,FALSE,array('suppress_error' => TRUE));
  }
}

/**
 * Implementation of hook_requirements().
 *
 * @ingroup tripal_phylogeny
 */
function tripal_phylogeny_requirements($phase) {
  $requirements = array();
  if ($phase == 'install') {
    // Make sure chado is installed.
    if (!$GLOBALS["chado_is_installed"]) {
      $requirements ['tripal_phylogeny'] = array(
        'title' => "tripal_phylogeny",
        'value' => "ERROR: Chado must be installed before this module can be enabled",
        'severity' => REQUIREMENT_ERROR,
      );
    }
  }
  return $requirements;
}

/**
 * Implementation of hook_schema().
 * Standard tripal linker table between a node and a phylotree record.
 * @ingroup tripal_phylogeny
 */
function tripal_phylogeny_schema() {
  $schema['chado_phylotree'] = array(
    'fields' => array(
      'vid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0
      ),
      'nid' => array(
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0
      ),
      'phylotree_id' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0
      )
    ),
    'indexes' => array(
      'chado_phylotree_idx1' => array('phylotree_id')
    ),
    'unique keys' => array(
      'chado_phylotree_uq1' => array('nid', 'vid'),
      'chado_phylotree_uq2' => array('vid')
    ),
    'primary key' => array('nid'),
  );

  return $schema;
}


/**
 * Adds controlled vocabulary terms needed by this module.
 *
 * @ingroup tripal_phylogeny
 */
function tripal_phylogeny_add_cvterms() {

}


/**
 * Implementation of hook_uninstall().
 */
function tripal_phylogeny_uninstall() {

    // Drop the MView table if it exists
    $mview_id =  tripal_get_mview_id('phylotree_count');
    if ($mview_id) {
        tripal_delete_mview($mview_id);
    }
    // Remove views integration.
    // Note: tripal_remove_views_intergration accepts table_name and priority in a key value form.
    $delete_view=array(
        'table_name' => 'phylotree_count',
        'priority' => '-1',
    );
    tripal_remove_views_integration($delete_view);

}

function tripal_phylogeny_add_mview(){
  // Materialized view addition.
  $sql_query="
    WITH count_genes as
      (SELECT count(*) count, t.phylotree_id
       FROM phylotree t, phylonode n
       WHERE n.phylotree_id = t.phylotree_id AND n.label is NOT NULL
       GROUP BY t.phylotree_id)
    SELECT
      phylotree.phylotree_id AS phylotree_phylotree_id,
      phylotree.name         AS phylotree_name,
      phylotree.comment      AS phylotree_comment,
      count_genes.count      AS total_count
    FROM chado.phylotree phylotree
      LEFT JOIN chado_phylotree chado_phylotree ON phylotree.phylotree_id = chado_phylotree.phylotree_id
      LEFT JOIN count_genes count_genes         ON phylotree.phylotree_id = count_genes.phylotree_id
  ";

  // Table Phylotree User Search description.
  $schema = array (
    'table' => 'phylotree_count',
    'fields' => array(
      'phylotree_phylotree_id' => array(
        'type' => 'int',
        'not null' => FALSE,
      ),
      'phylotree_name' => array(
        'type' => 'text',
        'not null' => FALSE,
      ),
      'phylotree_comment' => array(
        'type' => 'text',
        'not null' => FALSE,
      ),
      'total_count' => array(
        'type' => 'int',
        'not null' => TRUE,
      ),
    ),
    'primary key' => array('phylotree_phylotree_id'),
  );

  // Add a comment to make sure this view makes sense to the site administator.
  $comment = t('This view is used to provide a table for Phylotree User Search with total count.');
  tripal_add_mview('phylotree_count', 'tripal_phylogeny',  $schema, $sql_query, $comment);
}


/**
 * Integrate the qtl_search materialized view for use by Drupal Views and
 * our search form
 */

function tripal_phylogeny_integrate_view(){
  $integration = array (
    'table' => 'phylotree_count',
    'name' => 'phylotree_count',
    'type' => 'chado',
    'description' => '',
    'priority' => '-1',
    'base_table' => '1',
    'fields' => array (
      'phylotree_phylotree_id' => array (
        'name' => 'phylotree_phylotree_id',
        'title' => 'Phylotree ID',
        'description' => 'Phylotree ID',
        'type' => 'int',
        'handlers' => array (
          'filter' => array (
            'name' => 'views_handler_filter_numeric'
          ),
          'field' => array (
            'name' => 'views_handler_field_numeric'
          ),
          'sort' => array (
            'name' => 'views_handler_sort'
          ),
          'argument' => array (
            'name' => 'views_handler_argument_numeric'
          ),
          'relationship' => array (
            'name' => 'views_handler_relationship'
          )
        ),
        'joins' => array ()
      ),
      'phylotree_name' => array (
        'name' => 'phylotree_name',
        'title' => 'Family ID',
        'description' => 'Family ID',
        'type' => 'text',
        'handlers' => array (
          'filter' => array (
            'name' => 'tripal_views_handler_filter_select_string'
          ),
          'field' => array (
            'name' => 'views_handler_field'
          ),
          'sort' => array (
            'name' => 'views_handler_sort'
          ),
          'argument' => array (
            'name' => 'views_handler_argument_string'
          ),
          'relationship' => array (
            'name' => 'views_handler_relationship'
          )
        ),
        'joins' => array ()
      ),
      'phylotree_comment' => array (
        'name' => 'phylotree_comment',
        'title' => 'Description',
        'description' => 'Description',
        'type' => 'text',
        'handlers' => array (
          'filter' => array (
            'name' => 'tripal_views_handler_filter_select_string'
          ),
          'field' => array (
            'name' => 'views_handler_field'
          ),
          'sort' => array (
            'name' => 'views_handler_sort'
          ),
          'argument' => array (
            'name' => 'views_handler_argument_string'
          ),
          'relationship' => array (
            'name' => 'views_handler_relationship'
          )
        ),
        'joins' => array ()
      ),
      'total_count' => array (
        'name' => 'total_count',
        'title' => 'Total count',
        'description' => 'Total count',
        'type' => 'int',
        'handlers' => array (
          'filter' => array (
            'name' => 'views_handler_filter_numeric'
          ),
          'field' => array (
            'name' => 'views_handler_field'
          ),
          'sort' => array (
            'name' => 'views_handler_sort'
          ),
          'argument' => array (
            'name' => 'views_handler_argument_numeric'
          ),
          'relationship' => array (
            'name' => 'views_handler_relationship'
          )
        ),
        'joins' => array ()
      )
    )
  );

  // Add the array above that will integrate our qtl_search materialized view
  // for use with Drupal Views.
  tripal_add_views_integration($integration);
}

/**
 * Add any custom tables needed by this module.
 * - phylotreeprop: keep track of properties of phylotree
 *
 * @ingroup tripal_phylogeny
 */
function tripal_phylogeny_add_custom_tables() {
  $schema = array (
    'table' => 'phylotreeprop',
    'fields' => array (
      'phylotreeprop_id' => array (
        'type' => 'serial',
        'not null' => true,
      ),
      'phylotree_id' => array (
        'type' => 'int',
        'not null' => true,
      ),
      'type_id' => array (
        'type' => 'int',
        'not null' => true,
      ),
      'value' => array (
        'type' => 'text',
        'not null' => false,
      ),
      'rank' => array (
        'type' => 'int',
        'not null' => true,
        'default' => 0,
      ),
    ),
    'primary key' => array (
      0 => 'phylotreeprop_id',
    ),
    'unique keys' => array (
      'phylotreeprop_c1' => array (
        0 => 'phylotree_id',
        1 => 'type_id',
        2 => 'rank',
      ),
    ),
    'indexes' => array (
      'phylotreeprop_idx1' => array (
        0 => 'phylotree_id',
      ),
      'phylotreeprop_idx2' => array (
        0 => 'type_id',
      ),
    ),
    'foreign keys' => array (
      'cvterm' => array (
        'table' => 'cvterm',
        'columns' => array (
          'type_id' => 'cvterm_id',
        ),
      ),
      'phylotree' => array (
        'table' => 'phylotree',
        'columns' => array (
          'phylotree_id' => 'phylotree_id',
        ),
      ),
    ),
  );
  chado_create_custom_table('phylotreeprop', $schema, TRUE);
}

/**
 * Adds the vocabulary needed for storing taxonmies.
 */
function tripal_phylogeny_update_7200() {
  try {
    tripal_phylogeny_add_cvterms();
  }
  catch (\PDOException $e) {
    $error = $e->getMessage();
    throw new DrupalUpdateException('Failed to complete update' . $error);
  }
}