<?php
namespace nur\b\proc;

use nur\A;
use nur\shell;

/**
 * Class CmdPipe: une suite de commandes qui doivent s'exécuter avec les sorties
 * des unes connectées aux entrées des autres
 */
class CmdPipe extends AbstractCmd {
  /** @var string|null */
  private $input;
  /** @var string|null */
  private $output;

  function __construct(?array $cmds=null, ?string $input=null, ?string $output=null) {
    parent::__construct();
    if ($cmds !== null) {
      foreach ($cmds as $command) {
        $this->add($command);
      }
    }
    if ($input !== null) $this->setInput($input);
    if ($output !== null) $this->setOutput($output);
  }

  function addLiteral($cmd): self {
    A::append_nn($this->cmds, $cmd);
    return $this;
  }

  function add($cmd): self {
    if ($cmd !== null) {
      if (!($cmd instanceof ICmd)) {
        shell::fix_cmd($cmd);
      }
      $this->cmds[] = $cmd;
    }
    return $this;
  }

  function setInput(?string $input=null): self {
    $this->input = $input;
    return $this;
  }

  function setOutput(?string $output=null): self {
    $this->output = $output;
    return $this;
  }

  function getCmd(?string $sep=null): string {
    if ($sep === null) $sep = "\n";

    $actualCmd = [];
    A::append_nn($actualCmd, $this->getVars($sep));

    $parts = [];
    foreach ($this->cmds as $cmd) {
      if ($cmd instanceof ICmd) {
        $cmd = "(".$cmd->getCmd($sep).")";
      }
      $parts[] = $cmd;
    }
    $cmd = implode(" | ", $parts);

    $input = $this->input;
    $output = $this->output;
    if ($input !== null || $output !== null) {
      $parts = [];
      if ($input !== null) $parts[] = "<".escapeshellarg($input);
      $parts[] = $cmd;
      if ($output !== null) $parts[] = ">".escapeshellarg($output);
      $cmd = implode(" ", $parts);
    }
    A::append($actualCmd, $cmd);

    return implode($sep, $actualCmd);
  }
}