<?php

/**
 * IsisImporterBase: provides base ISIS import methods for importing data into
 * a Symfony project.
 *
 * Importing can be done either on actions or tasks.
 */
class sfIsisImporterBase extends IsisConnector
{
  /**
   * @var string $loglevel Log level.
   */
  var $loglevel = 'info';

  /**
   * @var int $processed Number of processed entries.
   */
  var $processed = 0;

  /**
   * Constructor.
   */
  public function __construct($loglevel = 'info')
  {
    parent::__construct();
    $this->loglevel = $loglevel;
  }

  /**
   * Create an ISIS configuration for a given database.
   *
   * @param  string $database Database name
   * @return array            Basic configuration
   */
  public function config($database)
  {
    // Default cinisis config file.
    $config = $this->isis->file();

    if (file_exists($config))
    {
      $this->log("Using Cinisis config file $config.");
      $config = sfYaml::load($config);
    }
    else {
      // Default configuration.
      $this->log("Cinisis config file not found, building configuration.");
      $config = array(
        'implementation' => 'BiblioIsis',
        );
    }

    $config['database'] = $database;
    return $config;
  }

  /**
   * List available ISIS databases.
   *
   * @return array Available databases
   */
  public function databases()
  {
    $files = glob(sfConfig::get('sf_lib_dir') .'/cinisis/schemas/*.yaml');
    foreach ($files as $file)
    {
      $databases[] = basename($file, '.yaml');
    }

    return $databases;
  }

  /**
   * Log dispatcher.
   *
   * @param string $message Log message
   * @param string $level   Log level
   */
  public function log($message, $level = 'info')
  {
    // Available log levels ordered by verbosity.
    $levels = array_flip(array('fatal', 'info', 'warn', 'error', 'debug'));

    // Log level checking.
    if (array_search($level, $levels) === FALSE)
    {
      $this->log("Invalid log level $level.", 'error');
      return;
    }
    elseif ($levels[$level] > $levels[$this->loglevel])
    {
      return;
    }

    // Dispatch.
    if ($this->section == 'action')
    {
      $this->caller->logMessage($message, $level);
    }
    else
    {
      $this->caller->logSection('isisImporter', "[$level] $message");
    }
  }

  /**
   * Progress notifier.
   *
   * @param int $n Row number
   */
  public function progress($n)
  {
    $this->processed = $n;

    if ($this->section == 'action')
    {
      $this->caller->output .= "Saved item $n\n";
    }
    else
    {
      // Progress bar is just shown if loglevel is 'fatal'.
      if ($this->loglevel == 'fatal')
      {
        $this->caller->progressBar($n, $this->entries);
      }
    }
  }

  /**
   * Guess a method name from a type.
   *
   * @param  string $type Mapping type
   * @return string       Method name
   */
  static function methodName($type)
  {
    return 'import'. ucfirst($type);
  }

  /**
   * Get the model foreign table id.
   *
   * @param  object $model Model
   * @return string        Model table id
   */
  static function getModelId($model) {
    return sfInflector::underscore(get_class($model)) .'_id';
  }

  /**
   * Get the relation foreign table id.
   *
   * @param  string $model Relation name
   * @return string        Relation table id
   */
  static function getRelationId($relation) {
    return sfInflector::underscore($relation) .'_id';
  }

  /**
   * Get the model and relation tablename.
   *
   * @param  object $model Model
   * @param  string $model Relation name
   * @return string        Relation table name
   */
  static function getModelRelation($model, $relation)
  {
    return sfInflector::camelize(self::getModelName($model)) . sfInflector::camelize($relation);
  }

  /**
   * Get the entity name from a subfield.
   *
   * @param  string $subfield Subfield name
   * @return string           Genre name
   */
  static function entityName($subfield)
  {
    return ucfirst($subfield);
  }  

  /**
   * Get the model name.
   *
   * @param  object $model Model
   * @return string        Model name
   */
  static function getModelName($model)
  {
    return get_class($model);
  }

  /**
   * After import procedure.
   */
  public function afterImport() {
    // Output ISIS log messages.
    if (is_array($this->isis->db->log))
    {
      foreach ($this->isis->db->log as $log)
      {
        $this->log("[isis] $log");
      }
    }

    $this->log("Finished mass import procedure.");
    $this->log("Total entries processed: $this->processed.");
  }
}