<?php

namespace Stack;

use Symfony\Component\HttpKernel\HttpKernelInterface;

class Builder
{
    private $specs;

    public function __construct()
    {
        $this->specs = new \SplStack();
    }

    public function unshift(/*$kernelClass, $args...*/)
    {
        if (func_num_args() > 0) {
            $spec = func_get_args();
            $this->specs->unshift($spec);
        }

        return $this;
    }

    public function push(/*$kernelClass, $args...*/)
    {
        if (func_num_args() > 0) {
            $spec = func_get_args();
            $this->specs->push($spec);
        }

        return $this;
    }

    public function resolve(HttpKernelInterface $app)
    {
        $middlewares = array($app);

        foreach ($this->specs as $spec) {
            $args = $spec;
            $firstArg = array_shift($args);

            if (is_callable($firstArg)) {
                $app = $firstArg($app);
            } else {
                $kernelClass = $firstArg;
                array_unshift($args, $app);

                $reflection = new \ReflectionClass($kernelClass);
                $app = $reflection->newInstanceArgs($args);
            }

            array_unshift($middlewares, $app);
        }

        return new StackedHttpKernel($app, $middlewares);
    }
}

<?php

namespace Stack;

use Symfony\Component\HttpKernel\HttpKernelInterface;

class Builder
{
    private $specs;

    public function __construct()
    {
        $this->specs = new \SplStack();
    }

    public function unshift(/*$kernelClass, $args...*/)
    {
        if (func_num_args() > 0) {
            $spec = func_get_args();
            $this->specs->unshift($spec);
        } else {
            throw new \InvalidArgumentException("Missing argument(s) when calling unshift");
        }

        return $this;
    }

    public function push(/*$kernelClass, $args...*/)
    {
        if (func_num_args() > 0) {
            $spec = func_get_args();
            $this->specs->push($spec);
        } else {
            throw new \InvalidArgumentException("Missing argument(s) when calling push");
        }

        return $this;
    }

    public function resolve(HttpKernelInterface $app)
    {
        $middlewares = array($app);

        foreach ($this->specs as $spec) {
            $args = $spec;
            $firstArg = array_shift($args);

            if (is_callable($firstArg)) {
                $app = $firstArg($app);
            } else {
                $kernelClass = $firstArg;
                array_unshift($args, $app);

                $reflection = new \ReflectionClass($kernelClass);
                $app = $reflection->newInstanceArgs($args);
            }

            array_unshift($middlewares, $app);
        }

        return new StackedHttpKernel($app, $middlewares);
    }
}

Throw Invalid Argument Exception when no args passed through to push and unshift
Throw Invalid Argument Exception when no args passed through to push and unshift
