<?php
/**
 * @file
 * Extends the services client connection with some configurations.
 */

/**
 * Implements hook_form_alter().
 */
function bassets_scc_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'ctools_export_ui_edit_item_form') {
    if ($form_state['plugin']['schema'] == 'services_client_connection') {
      $form['bassets'] = array(
        '#type' => 'fieldset',
        '#title' => t('Bassets settings'),
      );
      $scheme_options = array();
      foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) {
        $scheme_options[$scheme] = $stream_wrapper['name'];
      }
      $connections = array();
      if (module_exists('bassets_client')) {
        $connections['server'] = t('Server');
      }
      if (module_exists('bassets_server')) {
        $connections['client'] = t('Client');
      }
      $conf = isset($form_state['item']->config['bassets']) ? $form_state['item']->config['bassets'] : _bassets_scc_defaults();
      $form['bassets']['connection_type'] = array(
        '#type' => 'select',
        '#title' => t('Connection type'),
        '#options' => $connections,
        '#default_value' => $conf['connection_type'],
        '#empty_value' => '',
      );
      // The following settings are only for clients.
      if (isset($connections['server'])) {
        $form['bassets']['scheme'] = array(
          '#type' => 'select',
          '#title' => t('File system'),
          '#options' => $scheme_options,
          '#default_value' => $conf['scheme'],
          '#description' => t('Derivates of images will be stored in this file system. But nevertheless delivered through the "Bassets" stream wrapper.'),
          '#states' => array(
            'visible' => array(
              ':input[name="connection_type"]' => array('value' => 'server'),
            ),
          ),
        );
        $fileowner = '';
        if (!empty($conf['fileowner'])) {
          $account = user_load($conf['fileowner']);
          if ($account->uid != 1) {
            $fileowner = $account->name;
          }
        }
        $form['bassets']['fileowner'] = array(
          '#type' => 'textfield',
          '#title' => t('File owner'),
          '#maxlength' => 60,
          '#autocomplete_path' => 'user/autocomplete',
          '#default_value' => $fileowner,
          '#description' => t('This is the default file owner of a Bassets file. Leave blank for user 1.'),
          '#states' => array(
            'visible' => array(
              ':input[name="connection_type"]' => array('value' => 'server'),
            ),
          ),
        );
      }
      $form['#submit'][] = 'bassets_scc_form_submit_connection';
      $form['#validate'][] = 'bassets_scc_form_validate_connection';
    }
  }
  elseif ($form_id == 'ctools_export_ui_delete_confirm_form') {
    if ($form_state['plugin']['schema'] == 'services_client_connection') {
      $form['#validate'][] = 'bassets_scc_form_validate_deletion';
    }
  }
}

/**
 * Default values for a connection to a bassets server/client.
 *
 * @return array
 *   Default values.
 */
function _bassets_scc_defaults() {
  return array(
    'connection_type' => '',
    'scheme' => file_default_scheme(),
    'fileowner' => 1,
  );
}

/**
 * Validation handler for a ctools_export_ui_edit_item_form() form.
 *
 * @see bassets_scc_form_alter()
 */
function bassets_scc_form_validate_connection($form, &$form_state) {
  if (!empty($form_state['values']['connection_type']) && empty($form_state['values']['services_client_id'])) {
    form_set_error('services_client_id', t('The "Remote client ID" is required.'));
    return;
  }
}

/**
 * Submit handler for a ctools_export_ui_edit_item_form() form.
 *
 * @see bassets_scc_form_alter()
 */
function bassets_scc_form_submit_connection($form, &$form_state) {
  $bassets_conf = &$form_state['item']->config['bassets'];
  $old_values = $bassets_conf;
  // Reset our values.
  $bassets_conf = _bassets_scc_defaults();

  if (!empty($form_state['values']['connection_type'])) {
    $bassets_conf['connection_type'] = $form_state['values']['connection_type'];
  }
  if (!empty($form_state['values']['scheme'])) {
    $bassets_conf['scheme'] = $form_state['values']['scheme'];
    if ($old_values['scheme'] !== $bassets_conf['scheme']) {
      $name = isset($form_state['item']->name) ? $form_state['item']->name : NULL;
      $files = bassets_scc_load_files_by_server($name);
      foreach ($files as $file) {
        $uri = str_replace(file_uri_scheme($file->uri), $old_values['scheme'], $file->uri);
        image_path_flush($uri);
      }
    }
  }
  // This field it only available on the client side.
  if (!empty($form_state['values']['fileowner'])) {
    $account = user_load_by_name(array('name' => $form_state['values']['fileowner']));
    if (!empty($form_state['values']['fileowner']) && $account) {
      $bassets_conf['fileowner'] = $account->uid;
    }
  }
}

/**
 * Validate handler for the deletion of a service client connection.
 */
function bassets_scc_form_validate_deletion($form, &$form_state) {
  if (!empty($form_state['item']->services_client_id)) {
    $files = bassets_scc_load_files_by_server($form_state['item']->name);
    $count = count($files);
    if ($count) {
      form_set_error('', t('You can not delete the connection until you delete all files of the Bassets server.'));
    }
  }
}

/**
 * Loads all configuration of the connections for a certain type.
 *
 * @param string $type
 *   The machine name of the bassets client or server.
 *
 * @return array
 *   An array of configuration.
 */
function _bassets_scc_connections_load($type) {
  $cache = &drupal_static(__FUNCTION__);

  if (!isset($cache[$type])) {
    $connections = services_client_connection_load_all();
    foreach ($connections as $connection) {
      if (isset($connection->config['bassets']) && $connection->config['bassets']['connection_type'] == $type) {
        $cache[$type][$connection->name] = services_client_connection_load($connection->name);
      }
    }
  }

  return isset($cache[$type]) ? $cache[$type] : array();
}

/**
 * Detects the settings for a file. We store the server of the file in a table.
 *
 * @param string $fileuri
 *   Fileuri link bassets://123456.jpg.
 *
 * @return StdClass
 *   The bassets configuration.
 */
function bassets_scc_get_settings($fileuri = NULL) {
  $cache = &drupal_static(__FUNCTION__);
  if ($fileuri && !isset($cache[$fileuri]) && function_exists('bassets_client_load_bassets_file')) {
    $remote_file = bassets_client_load_bassets_file($fileuri);
    $connection = services_client_connection_load($remote_file->bassets_server);
    if (!empty($connection)) {
      $cache[$fileuri] = $connection->config['bassets'];
    }
  }
  else {
    $cache[$fileuri] = _bassets_scc_defaults();
  }
  return (object) $cache[$fileuri];
}

/**
 * Loads the files for server.
 *
 * @param string $bassets_server
 *   Machine name of the services client connection for a bassets server.
 *
 * @return array
 *   An array of file entitys.
 */
function bassets_scc_load_files_by_server($bassets_server = NULL) {
  $files = array();
  if (!empty($bassets_server) && module_exists('bassets_client')) {
    $files = bassets_client_load_bassets_files($bassets_server);
  }
  return $files;
}
