<?php
namespace nur\sery\os\proc;

use nur\sery\A;
use nur\sery\os\sh;

/**
 * Class AbstractCmdList: une séquence de commandes séparées par ;, && ou ||
 */
abstract class AbstractCmdList extends AbstractCmd {
  protected ?string $sep;

  function __construct(?string $sep, $cmd=null, ?string $input=null, ?string $output=null) {
    parent::__construct();
    $this->sep = $sep;
    $this->add($cmd, $input, $output);
  }

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

  function add($cmd, ?string $input=null, ?string $output=null): self {
    if ($cmd !== null) {
      if (!($cmd instanceof ICmd)) {
        sh::verifix_cmd($cmd, null, $input, $output);
      }
      $this->cmds[] = $cmd;
    }
    return $this;
  }

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

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

    $parts = [];
    foreach ($this->cmds as $cmd) {
      if ($cmd instanceof ICmd) {
        $cmd = "(".$cmd->getCmd($sep).")";
      }
      $parts[] = $cmd;
    }
    if (count($parts) == 1 && $exec) $parts[0] = "exec $parts[0]";
    $actualCmd[] = implode($this->sep ?? $sep, $parts);

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