<?php
/*
 * This file is part of the sfPropel13Plugin package.
 * (c) 2007 Joshua May <notjosh@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * @package    symfony.plugins
 * @subpackage sfPropel13Plugin
 * @author     Joshua May <notjosh@gmail.com>
 * @version    SVN: $Id$
 */

// ----
// Task runners
// ----
function run_propel_13_build_model($task, $args)
{
  _propel_convert_yml_schema(false, 'generated-');
  _propel_copy_xml_schema_from_plugins('generated-');
  _call_phing_13($task, 'om');
  $finder = pakeFinder::type('file')->name('generated-*schema.xml');
  pake_remove($finder, array('config', 'plugins'));
}

function run_propel_13_build_sql($task, $args)
{
  _propel_convert_yml_schema(false, 'generated-');
  _propel_copy_xml_schema_from_plugins('generated-');
  _call_phing_13($task, 'sql');
  $finder = pakeFinder::type('file')->name('generated-*schema.xml');
  pake_remove($finder, 'config');
}

function run_propel_13_insert_sql($task, $args)
{
  _propel_convert_yml_schema(false, 'generated-');
  _propel_copy_xml_schema_from_plugins('generated-');
  _call_phing_13($task, 'insert-sql');
  $finder = pakeFinder::type('file')->name('generated-*schema.xml');
  pake_remove($finder, 'config');
}

function run_propel_13_build_db($task, $args)
{
  _call_phing_13($task, 'create-db', false);
}

function run_propel_13_build_schema($task, $args)
{
  _call_phing_13($task, 'creole', false);

  // fix database name
  if (file_exists('config/schema.xml'))
  {
    $schema = file_get_contents('config/schema.xml');
    $schema = preg_replace('/<database\s+name="[^"]+"/s', '<database name="propel"', $schema);
    file_put_contents('config/schema.xml', $schema);
  }

  if (!isset($args[0]) || $args[0] != 'xml')
  {
    _propel_convert_xml_schema(false, '');
    $finder = pakeFinder::type('file')->name('schema.xml');
    pake_remove($finder, 'config');
  }
}

function run_propel_13_load_data($task, $args)
{
  //_init_db_path();
  //run_propel_load_data($task, $args)
  
  
  if (!count($args))
  {
    throw new Exception('You must provide the app.');
  }

  $app = $args[0];

  if (!is_dir(sfConfig::get('sf_app_dir').DIRECTORY_SEPARATOR.$app))
  {
    throw new Exception('The app "'.$app.'" does not exist.');
  }

  if (count($args) > 1 && $args[count($args) - 1] == 'append')
  {
    array_pop($args);
    $delete = false;
  }
  else
  {
    $delete = true;
  }

  $env = empty($args[1]) ? 'dev' : $args[1];

  // define constants
  define('SF_ROOT_DIR',    sfConfig::get('sf_root_dir'));
  define('SF_APP',         $app);
  define('SF_ENVIRONMENT', $env);
  define('SF_DEBUG',       true);

  // get configuration
  require_once SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php';
  
  _init_db_path();

  if (count($args) == 1)
  {
    if (!$pluginDirs = glob(sfConfig::get('sf_root_dir').'/plugins/*/data'))
    {
      $pluginDirs = array();
    }
    $fixtures_dirs = pakeFinder::type('dir')->name('fixtures')->in(array_merge($pluginDirs, array(sfConfig::get('sf_data_dir'))));
  }
  else
  {
    $fixtures_dirs = array_slice($args, 1);
  }

  $databaseManager = new sfDatabaseManager();
  $databaseManager->initialize();

  $data = new sfPropel13Data();
  $data->setDeleteCurrentData($delete);

  foreach ($fixtures_dirs as $fixtures_dir)
  {
    if (!is_readable($fixtures_dir))
    {
      continue;
    }

    pake_echo_action('propel', sprintf('load data from "%s"', $fixtures_dir));
    $data->loadData($fixtures_dir);
  }
}

function run_propel_13_dump_data($task, $args)
{
  if (!count($args))
  {
    throw new Exception('You must provide the app.');
  }

  $app = $args[0];

  if (!is_dir(sfConfig::get('sf_app_dir').DIRECTORY_SEPARATOR.$app))
  {
    throw new Exception('The app "'.$app.'" does not exist.');
  }

  if (!isset($args[1]))
  {
    throw new Exception('You must provide a filename.');
  }

  $filename = $args[1];

  $env = empty($args[2]) ? 'dev' : $args[2];

  // define constants
  define('SF_ROOT_DIR',    sfConfig::get('sf_root_dir'));
  define('SF_APP',         $app);
  define('SF_ENVIRONMENT', $env);
  define('SF_DEBUG',       true);

  // get configuration
  require_once SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php';

  _init_db_path();
  
  $databaseManager = new sfDatabaseManager();
  $databaseManager->initialize();

  if (!sfToolkit::isPathAbsolute($filename))
  {
    $dir = sfConfig::get('sf_data_dir').DIRECTORY_SEPARATOR.'fixtures';
    pake_mkdirs($dir);
    $filename = $dir.DIRECTORY_SEPARATOR.$filename;
  }

  pake_echo_action('propel', sprintf('dumping data to "%s"', $filename));

  $data = new sfPropel13Data();
  $data->dumpData($filename);
}

function run_propel_13_build_all($task, $args)
{
  run_propel_13_build_model($task, $args);
  run_propel_13_build_sql($task, $args);
  run_propel_13_insert_sql($task, $args);
}

function run_propel_13_build_all_load($task, $args)
{
  run_propel_13_build_all($task, $args);
  run_propel_13_load_data($task, $args);
}

function run_propel_13_convert_xml_schema($task, $args)
{
  _propel_convert_xml_schema(true);
}

function run_propel_13_convert_yml_schema($task, $args)
{
  _propel_convert_yml_schema(true);
}

// ----
// Internal functions
// ----
function _call_phing_13($task, $task_name, $check_schema = true)
{
  $schemas = pakeFinder::type('file')->name('*schema.xml')->relative()->follow_link()->in('config');
  if ($check_schema && !$schemas)
  {
    throw new Exception('You must create a schema.yml or schema.xml file.');
  }

  $pluginDir = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'vendor');
  if (false === strpos('propel-generator', get_include_path()))
  {
    set_include_path($pluginDir.'/propel-generator/classes'.PATH_SEPARATOR.get_include_path());
  }

  // needed to include the right Propel builders
  set_include_path(sfConfig::get('sf_symfony_lib_dir').PATH_SEPARATOR.get_include_path());
  set_include_path(sfConfig::get('sf_root_dir').PATH_SEPARATOR.get_include_path());

  // add phing 2.3 to include_path
  set_include_path(realpath(dirname(__FILE__) . '/../../lib/vendor/phing/classes') . PATH_SEPARATOR . get_include_path());

  // call phing targets
  pake_import('Phing', false);

  $options = array(
    'project.dir'       => sfConfig::get('sf_root_dir').'/config',
    'build.properties'  => 'propel.ini',
    'propel.output.dir' => sfConfig::get('sf_root_dir'),
  );
  pakePhingTask::call_phing($task, array($task_name), $pluginDir.'/propel-generator/build.xml', $options);

  chdir(sfConfig::get('sf_root_dir'));
}

function _init_db_path()
{
  $vendorDir = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'vendor');
  set_include_path($vendorDir.PATH_SEPARATOR.get_include_path());
}

// ----
// Task definitions
// ----
pake_desc('create classes for current model');
pake_task('propel-13-build-model', 'project_exists');

pake_desc('create sql for current model');
pake_task('propel-13-build-sql', 'project_exists');

pake_desc('create schema.xml from existing database');
pake_task('propel-13-build-schema', 'project_exists');

pake_desc('create schema.xml from schema.yml');
pake_task('propel-13-convert-yml-schema', 'project_exists');

pake_desc('create schema.yml from schema.xml');
pake_task('propel-13-convert-xml-schema', 'project_exists');

pake_desc('load data from fixtures directory');
pake_task('propel-13-load-data', 'project_exists');

pake_desc('dump data to fixtures directory');
pake_task('propel-13-dump-data', 'project_exists');

//pake_desc('create database for current model');
//pake_task('propel-13-build-db', 'project_exists');

pake_desc('insert sql for current model');
pake_task('propel-13-insert-sql', 'project_exists');

pake_desc('generate propel model and sql and initialize database');
pake_task('propel-13-build-all', 'project_exists');

pake_desc('generate propel model and sql and initialize database, and load data');
pake_task('propel-13-build-all-load', 'propel-13-build-all');
