<?php
namespace Drush\Commands\core;

use Drush\Commands\DrushCommands;
use Consolidation\SiteAlias\SiteAliasManagerAwareInterface;
use Consolidation\SiteAlias\SiteAliasManagerAwareTrait;

class SshCommands extends DrushCommands implements SiteAliasManagerAwareInterface
{
    use SiteAliasManagerAwareTrait;

    /**
     * Connect to a Drupal site's server via SSH.
     *
     * @command site:ssh
     * @option cd Directory to change to if Drupal root is not desired (the default).
     * @optionset_proc_build
     * @handle-remote-commands
     * @usage drush @mysite ssh
     *   Open an interactive shell on @mysite's server.
     * @usage drush @prod ssh ls /tmp
     *   Run "ls /tmp" on @prod site. If @prod is a site list, then ls will be executed on each site.
     * @usage drush @prod ssh git pull
     *   Run "git pull" on the Drupal root directory on the @prod site.
     * @aliases ssh,site-ssh
     * @topics docs:aliases
     */
    public function ssh(array $args, $options = ['cd' => true])
    {
        // n.b. we do not escape the first (0th) arg to allow `drush ssh 'ls /path'`
        // to work in addition to the preferred form of `drush ssh ls /path`.
        // Supporting the legacy form means that we cannot give the full path to an
        // executable if it contains spaces.
        for ($x = 1; $x < count($args); $x++) {
            $args[$x] = drush_escapeshellarg($args[$x]);
        }
        $command = implode(' ', $args);

        $alias = $this->siteAliasManager()->getSelf();
        if ($alias->isNone()) {
            throw new \Exception('A site alias is required. The way you call ssh command has changed to `drush @alias ssh`.');
        }

        // Local sites run their bash without SSH.
        if (!$alias->isRemote()) {
            $return = drush_invoke_process('@self', 'core-execute', [$command], ['escape' => false]);
            return $return['object'];
        }

        // We have a remote site - build ssh command and run.
        $interactive = false;
        $cd = $options['cd'];
        if (empty($command)) {
            $command = 'bash -l';
            $interactive = true;
        }

        $cmd = drush_shell_proc_build($alias, $command, $cd, $interactive);
        $status = drush_shell_proc_open($cmd);
        if ($status != 0) {
            throw new \Exception(dt('An error @code occurred while running the command `@command`', ['@command' => $cmd, '@code' => $status]));
        }
    }
}
