#!/usr/bin/php
<?php
/**
* jUpgradePro
*
* @version $Id:
* @package jUpgradePro
* @copyright Copyright (C) 2004 - 2017 Matware. All rights reserved.
* @author Matias Aguirre
* @email maguirre@matware.com.ar
* @link http://www.matware.com.ar/
* @license GNU General Public License version 2 or later; see LICENSE
*/
// We are a valid Joomla entry point.
define('_JEXEC', 1);

// Bootstrap the application.
require dirname(dirname(__FILE__)).'/bootstrap.php';

class jUpgradeProCli extends JApplicationCli
{
	/**
	* Ascii color array
	*
	* @var array
	* @since 1.0
	*/
	public $_c = array(
		'LIGHT_RED'   => "\033[1;31m",
		'LIGHT_GREEN' => "\033[1;32m",
		'YELLOW'      => "\033[1;33m",
		'LIGHT_BLUE'  => "\033[1;34m",
		'MAGENTA'     => "\033[1;35m",
		'LIGHT_CYAN'  => "\033[1;36m",
		'WHITE'       => "\033[1;37m",
		'NORMAL'      => "\033[0m",
		'BLACK'       => "\033[0;30m",
		'RED'         => "\033[0;31m",
		'GREEN'       => "\033[0;32m",
		'BROWN'       => "\033[0;33m",
		'BLUE'        => "\033[0;34m",
		'CYAN'        => "\033[0;36m",
		'BOLD'        => "\033[1m",
		'UNDERSCORE'  => "\033[4m",
		'REVERSE'     => "\033[7m",
	);

	/**
	* Class constructor.
	*
	* @return void
	*
	* @since 2.5.0
	*/
	public function __construct()
	{
		// Call the parent __construct method so it bootstraps the application class.
		parent::__construct();

		// Getting the parameters
		$this->params = new JRegistry(new JConfig);

		// Creating dabatase instance for this installation
		$this->_db = JFactory::getDBO();

		// Add the logger.
		JLog::addLogger(
			// Pass an array of configuration options
			array(
				// Set the name of the log file
				'text_file' => JPATH_SITE.'/logs/jupgradepro.log.php'
			)
		);

		// Initialize step model
		$this->step_model = new jUpgradeProModelStep;

		// Initialize checks model
		$this->migrate_model = new jUpgradeProModelMigrate;

		// Initialize checks model
		$this->extensions_model = new jUpgradeProModelExtensions;
	}

	/**
	 * Screen
	 *
	 * @return	none
	 * @since	2.5.0
	 */
	public function screen()
	{
		// Print help
		$this->out();
		$this->out(' jUpgradeProCli v3.8.0');
		$this->out();
		$this->out(' Author: Matias Aguirre (maguirre@matware.com.ar)');
		$this->out(' URL: http://www.matware.com.ar');
		$this->out(' License: GNU/GPL http://www.gnu.org/licenses/gpl-2.0-standalone.html');
		$this->out();
	}

	/**
	 * execute
	 *
	 * @return	none
	 * @since	2.5.0
	 */
	public function execute()
	{
		// Show project info
		$this->screen();

		// Running the checks
		$checks = new jUpgradeProModelChecks;

		try {
			$checks->checks();
		} catch (Exception $e) {
			$checks->returnError (500, $e->getMessage());
		}

		// Running the cleanup
		$cleanup = new jUpgradeProModelCleanup;

		try {
			$cleanup->cleanup();
		} catch (Exception $e) {
			$cleanup->returnError (500, $e->getMessage());
		}

		// Migrating Joomla! core
		try {
			$this->migrateCore();
		} catch (Exception $e) {
			$this->returnError (500, $e->getMessage());
		}

		// Migration 3rd party extensions
		try {
			$this->migrateExtensions();
		} catch (Exception $e) {
			$this->returnError (500, $e->getMessage());
		}
	}

	/**
	 * Migrate Joomla! core
	 *
	 * @return	none
	 * @since	2.5.0
	 */
	public function migrateCore()
	{
		$finished = false;
		$method = $this->params->get('method');


		$oldver = JUpgradeproHelper::getVersion('old');
		$newver = JUpgradeproHelper::getVersion('new');

		$this->out("{$this->_c['WHITE']}-------------------------------------------------------------------------------------------------");
		$this->out("{$this->_c['WHITE']}|  {$this->_c['BLUE']}	Migrating Joomla! {$oldver} core data to Joomla! {$newver}");

		// Start benchmark
		$benchmark_start = microtime(true);

		while (!$finished)
		{
			$this->out("{$this->_c['WHITE']}-------------------------------------------------------------------------------------------------");

			// Getting the current step
			$step = json_decode($this->step_model->step());

			if ( empty($step->id) || !isset($step->stop)) {
				break;
			}

			$this->out("{$this->_c['WHITE']}|  {$this->_c['GREEN']}[{$step->id}] Migrating {$step->name} (Start:{$step->start} - Stop: {$step->stop} - Total: {$step->total})");

			//echo "{$this->_c['WHITE']}| DEBUG: " . print_r($step);

			// Start benchmark
			$time_start = microtime(true);

			$this->out("{$this->_c['WHITE']}|  {$this->_c['RED']}[{$this->_c['YELLOW']}", false);
			if ($step->stop != -1) {
				$response = $this->migrate_model->migrate($step->name, false);
			}
			$this->out( "{$this->_c['RED']}]" );

			$time_end = microtime(true);
			$time = $time_end - $time_start;
			$this->out( "{$this->_c['WHITE']}|  {$this->_c['CYAN']}[Benchmark] ".round($time, 3)." seconds." );
		}

		$benchmark_end = microtime(true);
		$benchmark = $benchmark_end - $benchmark_start;
		$this->out( "\n{$this->_c['CYAN']}[[TOTAL Benchmark]] ".round($benchmark, 3)." seconds" );

	} // end method

	/**
	 * Migrate Joomla! 3rd party extensions
	 *
	 * @return	none
	 * @since	2.5.0
	 */
	public function migrateExtensions()
	{
		$finished = false;
		$method = $this->params->get('method');
		$skip = $this->params->get('skip_extensions');

		if ($skip == 1)
			exit;

		$this->out("{$this->_c['WHITE']}-------------------------------------------------------------------------------------------------");
		$this->out("{$this->_c['WHITE']}|  {$this->_c['BLUE']}	Migrating Joomla! 3rd party extensions");

		// Start benchmark
		$benchmark_start = microtime(true);

		// Check for 3rd party extensions
		$result = $this->extensions_model->extensions();

		while (!$finished)
		{
			$this->out("{$this->_c['WHITE']}-------------------------------------------------------------------------------------------------");

			// Getting the current step
			$step = json_decode($this->step_model->step(false, false, 'tables'));

			if ( empty($step->id) || !isset($step->stop)) {
				break;
			}

			$this->out("{$this->_c['WHITE']}|  {$this->_c['GREEN']}[{$step->id}] Migrating {$step->name} (Start:{$step->start} - Stop: {$step->stop} - Total: {$step->total})");

			// Start benchmark
			$time_start = microtime(true);

			echo "{$this->_c['WHITE']}|  {$this->_c['RED']}[{$this->_c['YELLOW']}";
			if ($step->stop != -1) {
				$response = $this->migrate_model->migrate($step->name, false, 'tables');
			}
			$this->out( "{$this->_c['RED']}]" );

			$time_end = microtime(true);
			$time = $time_end - $time_start;
			$this->out( "{$this->_c['WHITE']}|  {$this->_c['CYAN']}[Benchmark] ".round($time, 3)." seconds." );
		}

		$benchmark_end = microtime(true);
		$benchmark = $benchmark_end - $benchmark_start;
		$this->out( "\n{$this->_c['CYAN']}[[TOTAL Extensions Benchmark]] ".round($benchmark, 3)." seconds" );

	} // end method

	/**
	 * returnError
	 *
	 * @return	none
	 * @since	2.5.0
	 */
	public function returnError ($number, $text)
	{
		$message['number'] = $number;
		$message['text'] = JText::_($text);
		echo json_encode($message);
		exit;
	}

} // end class

// Wrap the execution in a try statement to catch any exceptions thrown anywhere in the script.
try
{
	// Instantiate the application object, passing the class name to JCli::getInstance
	// and use chaining to execute the application.
	JApplicationCli::getInstance('jUpgradeProCli')->execute();
}
catch (Exception $e)
{
	// An exception has been caught, just echo the message.
	fwrite(STDOUT, $e->getMessage() . "\n");
	exit($e->getCode());
}
