<?php
/**
 * @file
 *
 * Installation file for Ultimate Cron
 */

/**
 * Implements hook_schema().
 */
function ultimate_cron_schema() {
  $schema = array();

  $schema['ultimate_cron'] = array(
    'description' => 'Cron job function list',
    'export' => array(
      'key' => 'name',
      'key name' => 'Function name',
      'primary key' => 'fid',
      'identifier' => 'name',
      'default hook' => 'default_ultimate_cron_function',
      'save callback' => 'ultimate_cron_crud_save',
      'api' => array(
        'owner' => 'ultimate_cron',
        'api' => 'default_ultimate_cron_functions',
        'minimum_version' => 1,
        'current_version' => 1,
      ),
    ),
    'fields' => array(
      'fid' => array(
        'description' => 'Function ID',
        'type' => 'serial',
        'size' => 'normal',
        'not null' => TRUE,
        'no export' => TRUE,
      ),
      'name' => array(
        'description' => 'Function name',
        'type' => 'varchar',
        'length' => 127,
        'not null' => TRUE,
        'default' => '',
      ),
      'settings' => array(
        'description' => 'Settings',
        'type' => 'text',
        'serialize' => TRUE,
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('fid'),
    'unique keys' => array(
      'uniq_name' => array('name')
    ),
  );

  $schema['ultimate_cron_log'] = array(
    'description' => 'Logs',
    'fields' => array(
      'lid' => array(
        'description' => 'Log ID',
        'type' => 'serial',
        'size' => 'normal',
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => 'Function name',
        'type' => 'varchar',
        'length' => 127,
        'not null' => TRUE,
        'default' => '',
      ),
      'start_stamp' => array(
        'description' => 'Timstamp of execution start',
        'type' => 'float',
        'size' => 'big',
        'not null' => TRUE,
        'default' => 0,
      ),
      'end_stamp' => array(
        'description' => 'Timstamp of execution end',
        'type' => 'float',
        'size' => 'big',
        'not null' => TRUE,
        'default' => 0,
      ),
      'service_host' => array(
        'description' => 'Service host',
        'type' => 'varchar',
        'length' => 127,
        'not null' => TRUE,
        'default' => '',
      ),
      'exec_status' => array(
        'description' => 'Status of the execution',
        'type' => 'int',
        'size' => 'normal',
        'not null' => FALSE,
        'default' => NULL,
      ),
      'severity' => array(
        'description' => 'Log level severity',
        'type' => 'int',
        'size' => 'normal',
        'not null' => TRUE,
        'default' => -1,
      ),
      'msg' => array(
        'description' => 'Message',
        'type' => 'text',
        'not null' => FALSE,
      ),
    ),
    'primary key' => array('lid'),
    'indexes' => array(
       'idx_last' => array('name', 'start_stamp'),
       'idx_count' => array('name', 'end_stamp'),
    ),
  );

  return $schema;
}

/**
 * Implements hook_enable().
 */
function ultimate_cron_enable() {
  // Disable built-in poor mans cron
  variable_set('cron_safe_threshold', 0);
}

/**
 * Implements hook_uninstall().
 */
function ultimate_cron_uninstall() {
  variable_del('ultimate_cron_simultaneous_connections');
  variable_del('ultimate_cron_rule');
  variable_del('ultimate_cron_cleanup_log');
  variable_del('ultimate_cron_catch_up');
  variable_del('ultimate_cron_queue_polling_latency');
  variable_del('ultimate_cron_queue_lease_time');
  variable_del('ultimate_cron_poorman');
  variable_del('ultimate_cron_launch_window');
  variable_del('ultimate_cron_max_execution_time');
}


/**
 * Implements hook_requirements().
 */
function ultimate_cron_requirements($phase) {
  $response = array();
  switch ($phase) {
    case 'install':
      return $response;
    case 'runtime':
      $t = get_t();
      $response['title'] = 'Ultimate Cron';
      $response['value'] = $t('OK');
      $response['severity'] = REQUIREMENT_OK;
      if ($modules = _ultimate_cron_incompatible_modules()) {
        $response['severity'] = REQUIREMENT_ERROR;
        $response['value'] = $t('Ultimate Cron is DISABLED!');
        $response['description'] = $t('%modules is installed on the system, but is incompatible with Ultimate Cron.<br/>Please disable the modules %modules.<br/>You might want to !url settings first.', array('%modules' => join(', ', $modules), '!url' => l(t('import'), 'admin/settings/cron/import')));
      }
      if (ini_get('safe_mode')) {
        $desc = $t('Safe mode enabled. Ultimate Cron is unable to control maximum execution time for cron jobs. This may cause cron jobs to end prematurely.');
        if ($response['severity'] < REQUIREMENT_WARNING) {
          $response['severity'] = REQUIREMENT_WARNING;
          $response['value'] = $t('Safe mode enabled');
          $response['description'] = $desc;
        }
        else {
          $response['description'] .= '<br/>' . $desc;
        }
      }
      $result = array();
      $result['ultimate_cron'] = $response;
      return $result;
  }
}

/**
 * Major version upgrade of Drupal
 */
function ultimate_cron_update_7000(&$context) {
  $context['sandbox']['major_version_upgrade'] = array(
    7101 => TRUE,
    7102 => TRUE,
    7103 => TRUE,
    7104 => TRUE,
    7105 => TRUE,
    7106 => TRUE,
    7107 => TRUE,
    7108 => FALSE,
  );
}

/**
 * Move messages to log table.
 */
function ultimate_cron_update_7101(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7101])) {
    // This udate is already part of latest 6.x
    return;
  }
  $schema_version = (int)(db_query("SELECT schema_version FROM {system} WHERE name = 'ultimate_cron'")->fetchField());
  if ($schema_version >= 7000) {
    // Old hook_update_N was 7000
    return;
  }
  db_add_field('ultimate_cron_log', 'msg', array(
    'description' => 'Message',
    'type' => 'text',
    'not null' => FALSE,
  ));
  db_query("UPDATE {ultimate_cron_log} l JOIN {ultimate_cron_log_message} m ON l.lid = m.lid SET l.msg = m.msg");
  db_drop_table('ultimate_cron_log_message');
}

/**
 * Convert polling latenct from microseconds to miliseconds.
 */
function ultimate_cron_update_7102(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7102])) {
    // This udate is already part of latest 6.x
    return;
  }
  $schema_version = (int)(db_query("SELECT schema_version FROM {system} WHERE name = 'ultimate_cron'")->fetchField());
  if ($schema_version >= 7001) {
    // Old hook_update_N was 7001
    return;
  }
  // Convert polling latency from microseconds to miliseconds.
  $polling_latency = variable_get('ultimate_cron_queue_polling_latency', NULL);
  if ($polling_latency) {
    $polling_latency /= 1000;
    variable_set('ultimate_cron_queue_polling_latency', $polling_latency);
  }
}

/**
 * Merge ultimate_cron_function and ultimate_cron_configuration into ultimate_cron
 */
function ultimate_cron_update_7103(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7103])) {
    // This udate is already part of latest 6.x
    return;
  }
  $schema_version = (int)(db_query("SELECT schema_version FROM {system} WHERE name = 'ultimate_cron'")->fetchField());
  if ($schema_version >= 7002) {
    // Old hook_update_N was 7002
    return;
  }
  $schema = ultimate_cron_schema();
  db_create_table('ultimate_cron', $schema['ultimate_cron']);
  db_query("INSERT INTO {ultimate_cron} SELECT f.fid, f.function, c.configuration AS settings FROM ultimate_cron_function f LEFT JOIN {ultimate_cron_configuration} c ON f.fid = c.fid");
  db_drop_table('ultimate_cron_function');
  db_drop_table('ultimate_cron_configuration');
}

/**
 * Switch from fid to function name in ultimate_cron_log
 */
function ultimate_cron_update_7104(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7104])) {
    // This udate is already part of latest 6.x
    return;
  }
  $schema_version = (int)(db_query("SELECT schema_version FROM {system} WHERE name = 'ultimate_cron'")->fetchField());
  if ($schema_version >= 7003) {
    // Old hook_update_N was 7003
    return;
  }
  db_add_field('ultimate_cron_log', 'function', array(
        'description' => 'Function name',
        'type' => 'varchar',
        'length' => 127,
        'not null' => TRUE,
        'default' => '',
        'initial' => 'function',
      ));
  $fids = db_select('ultimate_cron_log', 'u')->fields('u', array('fid'))->distinct()->execute();
  while ($fid = $fids->fetchObject()) {
    $function = db_select('ultimate_cron', 'u')->fields('u', array('function'))->condition('fid', $fid->fid, '=')->execute()->fetchObject();
    db_update('ultimate_cron_log')->fields(array('function' => $function->function))->condition('fid', $fid->fid, '=')->execute();
  }
  db_drop_field('ultimate_cron_log', 'fid');
  db_drop_index('ultimate_cron_log', 'idx_last');
  db_drop_index('ultimate_cron_log', 'idx_count');
  db_add_index('ultimate_cron_log', 'idx_last', array('function', 'start'));
  db_add_index('ultimate_cron_log', 'idx_count', array('function', 'end'));
}

/**
 * Add missing index to database
 */
function ultimate_cron_update_7105(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7105])) {
    // This udate is already part of latest 6.x
    return;
  }
  $items = db_select('ultimate_cron')
             ->fields('ultimate_cron', array('fid', 'function'))
             ->orderBy('fid', 'ASC')
             ->execute()
             ->fetchAllAssoc('fid', PDO::FETCH_ASSOC);
  $fids = array();
  $keep = array();
  foreach ($items as $item) {
    if (isset($keep[$item['function']])) {
      $fids[] = $keep[$item['function']];
    }
    $keep[$item['function']] = $item['fid'];
  }
  if ($fids) {
    db_delete('ultimate_cron')
      ->condition('fid', $fids)
      ->execute();
  }
  db_add_unique_key('ultimate_cron', 'uniq_function', array('function'));
}

/**
 * Change schema to SQL 99 compliance
 */
function ultimate_cron_update_7106(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7106])) {
    // This udate is already part of latest 6.x
    return;
  }
  db_drop_unique_key('ultimate_cron', 'idx_function');
  db_change_field('ultimate_cron', 'function', 'name', array(
    'description' => 'Function name',
    'type' => 'varchar',
    'length' => 127,
    'not null' => TRUE,
    'default' => '',
  ));
  db_add_unique_key('ultimate_cron', 'idx_name', array('name'));
  
  db_change_field('ultimate_cron_log', 'function', 'name', array(
    'description' => 'Function name',
    'type' => 'varchar',
    'length' => 127,
    'not null' => TRUE,
    'default' => '',
  ));
  db_change_field('ultimate_cron_log', 'start', 'start_stamp', array(
    'description' => 'Timstamp of execution start',
    'type' => 'float',
    'size' => 'big',
    'not null' => TRUE,
    'default' => 0,
  ));
  db_change_field('ultimate_cron_log', 'end', 'end_stamp', array(
    'description' => 'Timstamp of execution end',
    'type' => 'float',
    'size' => 'big',
    'not null' => TRUE,
    'default' => 0,
  ));
  db_change_field('ultimate_cron_log', 'status', 'exec_status', array(
    'description' => 'Status of the execution',
    'type' => 'int',
    'size' => 'normal',
    'not null' => FALSE,
    'default' => NULL,
  ));
}

/**
 * Add service host to log.
 */
function ultimate_cron_update_7107(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7107])) {
    // This udate is already part of latest 6.x
    return;
  }
  db_add_field('ultimate_cron_log', 'service_host', array(
    'description' => 'Service host',
    'type' => 'varchar',
    'length' => 127,
    'not null' => TRUE,
    'default' => '',
  ));
}

/**
 * Add severity level to log.
 */
function ultimate_cron_update_7108(&$context) {
  if (!empty($context['sandbox']['major_version_upgrade'][7108])) {
    // This udate is already part of latest 6.x
    return;
  }
  db_add_field('ultimate_cron_log', 'severity', array(
    'description' => 'Log level severity',
    'type' => 'int',
    'size' => 'normal',
    'not null' => TRUE,
    'default' => -1,
  ));
}