<?php

namespace Symfony\Components\Console\Tester;

use Symfony\Components\Console\Command\Command;
use Symfony\Components\Console\Input\ArrayInput;
use Symfony\Components\Console\Output\StreamOutput;

class CommandTester
{
  protected $command;
  protected $display;
  protected $input;
  protected $output;

  /**
   * Constructor.
   *
   * @param Command $command A Command instance to test.
   */
  public function __construct(Command $command)
  {
    $this->command = $command;
  }

  /**
   * Executes the command.
   *
   * Available options:
   *
   *  * interactive: Sets the input interactive flag
   *  * decorated:   Sets the output decorated flag
   *  * verbosity:   Sets the output verbosity flag
   *
   * @param array $input   An array of arguments and options
   * @param array $options An array of options
   */
  public function execute(array $input, array $options = array())
  {
    $this->input = new ArrayInput(array_merge($input, array('command' => $this->command->getFullName())));
    if (isset($options['interactive']))
    {
      $this->input->setInteractive($options['interactive']);
    }

    $this->output = new StreamOutput(fopen('php://memory', 'w', false));
    if (isset($options['decorated']))
    {
      $this->output->setDecorated($options['decorated']);
    }
    if (isset($options['verbosity']))
    {
      $this->output->setVerbosity($options['verbosity']);
    }

    $ret = $this->command->run($this->input, $this->output);

    rewind($this->output->getStream());

    return $this->display = stream_get_contents($this->output->getStream());
  }

  /**
   * Gets the display returned by the last execution of the command.
   *
   * @return string The display
   */
  public function getDisplay()
  {
    return $this->display;
  }

  /**
   * Gets the input instance used by the last execution of the command.
   *
   * @return InputInterface The current input instance
   */
  public function getInput()
  {
    return $this->input;
  }

  /**
   * Gets the output instance used by the last execution of the command.
   *
   * @return OutputInterface The current output instance
   */
  public function getOutput()
  {
    return $this->output;
  }
}