#!/usr/bin/env php
<?php

/*
 * This file is part of PsySH
 *
 * (c) 2013 Justin Hileman
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* <<< */
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require(__DIR__ . '/../vendor/autoload.php');
} elseif (is_file(__DIR__ . '/../../../autoload.php')) {
    require(__DIR__ . '/../../../autoload.php');
} else {
    die(
        'You must set up the Psy Shell dependencies, run the following commands:' . PHP_EOL .
        'curl -s http://getcomposer.org/installer | php' . PHP_EOL .
        'php composer.phar install' . PHP_EOL
    );
}
/* >>> */

use Psy\Configuration;
use Psy\Shell;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;

// If the psysh binary was included directly, assume they just wanted an
// autoloader and bail early.
if (version_compare(PHP_VERSION, '5.3.6', '<')) {
    $trace = debug_backtrace();
} elseif (version_compare(PHP_VERSION, '5.4.0', '<')) {
    $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
} else {
    $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
}

if (Shell::isIncluded($trace)) {
    unset($trace);

    return;
}

// Clean up after ourselves.
unset($trace);

call_user_func(function() {
    $usageException = null;

    $input = new ArgvInput();
    try {
        $input->bind(new InputDefinition(array(
            new InputOption('help',    'h', InputOption::VALUE_NONE),
            new InputOption('config',  'c', InputOption::VALUE_REQUIRED),
            new InputOption('version', 'v', InputOption::VALUE_NONE),

            new InputArgument('include', InputArgument::IS_ARRAY),
        )));
    } catch (\RuntimeException $e) {
        $usageException = $e;
    }

    $config = array();

    // Handle --config
    if ($configFile = $input->getOption('config')) {
        $config['configFile'] = $configFile;
    }

    $shell = new Shell(new Configuration($config));

    // Handle --help
    if ($usageException !== null || $input->getOption('help')) {
        if ($usageException !== null) {
            echo $usageException->getMessage() . PHP_EOL . PHP_EOL;
        }

        $version = $shell->getVersion();
        $name    = basename(reset($_SERVER['argv']));
        echo <<<EOL
$version

Usage:
  $name [--version] [--help] [files...]

Options:
  --help     -h Display this help message.
  --config   -c Use an alternate PsySH config file location.
  --version  -v Display the PsySH version.

EOL;
        exit($usageException === null ? 0 : 1);
    }


    // Handle --version
    if ($input->getOption('version')) {
        echo $shell->getVersion() . PHP_EOL;
        exit(0);
    }

    // Pass additional arguments to Shell as 'includes'
    $shell->setIncludes($input->getArgument('include'));

    try {
        // And go!
        $shell->run();
    } catch (Exception $e) {
        echo $e->getMessage() . PHP_EOL;

        // TODO: this triggers the "exited unexpectedly" logic in the
        // ForkingLoop, so we can't exit(1) after starting the shell...
        // fix this :)

        // exit(1);
    }
});
