/**
  * Create parameters for the method and their documentation
  *
  * @param Operation $operation
  * @param string[]  $queryParamDocumentation
  * @param Context   $context
  *
  * @return array
  */
 protected function createParameters(Operation $operation, $queryParamDocumentation, Context $context)
 {
     $documentationParams = [];
     $methodParameters = [];
     if ($operation->getOperation()->getParameters()) {
         foreach ($operation->getOperation()->getParameters() as $parameter) {
             if ($parameter instanceof PathParameterSubSchema) {
                 $methodParameters[] = $this->pathParameterGenerator->generateMethodParameter($parameter, $context);
                 $documentationParams[] = sprintf(' * @param %s', $this->pathParameterGenerator->generateDocParameter($parameter, $context));
             }
         }
         foreach ($operation->getOperation()->getParameters() as $parameter) {
             if ($parameter instanceof BodyParameter) {
                 $methodParameters[] = $this->bodyParameterGenerator->generateMethodParameter($parameter, $context);
                 $documentationParams[] = sprintf(' * @param %s', $this->bodyParameterGenerator->generateDocParameter($parameter, $context));
             }
         }
     }
     $documentationParams[] = " * @param array  \$parameters List of parameters";
     $documentationParams[] = " * ";
     $documentationParams = array_merge($documentationParams, array_map(function ($doc) {
         return " *     " . $doc;
     }, $queryParamDocumentation));
     $documentationParams[] = " * ";
     $documentationParams[] = " * @param string \$fetch      Fetch mode (object or response)";
     $methodParameters[] = new Param('parameters', new Expr\Array_());
     $methodParameters[] = new Param('fetch', new Expr\ConstFetch(new Name('self::FETCH_OBJECT')));
     return [$documentationParams, $methodParameters];
 }
 /**
  * Generate a method for an operation
  *
  * @param string    $name
  * @param Operation $operation
  * @param Context   $context
  *
  * @return Stmt\ClassMethod
  */
 public function generate($name, Operation $operation, Context $context)
 {
     $methodParameters = [];
     $documentation = ['/**'];
     $bodyParameter = null;
     $queryParamStatements = [];
     $replaceArgs = [];
     $queryParamVariable = new Expr\Variable('queryParam');
     $url = $operation->getPath();
     if ($operation->getOperation()->getDescription()) {
         $documentation[] = sprintf(" * %s", $operation->getOperation()->getDescription());
     }
     if ($operation->getOperation()->getParameters()) {
         $documentation[] = " * ";
         foreach ($operation->getOperation()->getParameters() as $parameter) {
             if ($parameter instanceof BodyParameter) {
                 $methodParameters[] = $this->bodyParameterGenerator->generateMethodParameter($parameter);
                 $documentation[] = sprintf(' * @param %s', $this->bodyParameterGenerator->generateDocParameter($parameter));
                 $bodyParameter = $parameter;
             }
             if ($parameter instanceof FormDataParameterSubSchema) {
                 $queryParamStatements = array_merge($queryParamStatements, $this->formDataParameterGenerator->generateQueryParamStatements($parameter, $queryParamVariable));
             }
             if ($parameter instanceof HeaderParameterSubSchema) {
                 $queryParamStatements = array_merge($queryParamStatements, $this->formDataParameterGenerator->generateQueryParamStatements($parameter, $queryParamVariable));
             }
             if ($parameter instanceof PathParameterSubSchema) {
                 $methodParameters[] = $this->pathParameterGenerator->generateMethodParameter($parameter);
                 $documentation[] = sprintf(' * @param %s', $this->pathParameterGenerator->generateDocParameter($parameter));
                 $replaceArgs[] = new Arg(new Expr\Variable($parameter->getName()));
                 $url = str_replace('{' . $parameter->getName() . '}', '%s', $url);
             }
             if ($parameter instanceof QueryParameterSubSchema) {
                 $queryParamStatements = array_merge($queryParamStatements, $this->queryParameterGenerator->generateQueryParamStatements($parameter, $queryParamVariable));
             }
         }
     }
     $methodParameters[] = new Param('parameters', new Expr\Array_());
     $methodParameters[] = new Param('fetch', new Expr\ConstFetch(new Name('self::FETCH_OBJECT')));
     $documentation[] = " * @param array  \$parameters List of parameters";
     $documentation[] = " * @param string \$fetch      Fetch mode (object or response)";
     $documentation[] = " *";
     $documentation[] = " * @return \\Psr\\Http\\Message\\ResponseInterface";
     $documentation[] = " */";
     $methodBody = [new Expr\Assign($queryParamVariable, new Expr\New_(new Name('QueryParam')))];
     $methodBody = array_merge($methodBody, $queryParamStatements);
     $methodBody = array_merge($methodBody, [new Expr\Assign(new Expr\Variable('url'), new Expr\FuncCall(new Name('sprintf'), array_merge([new Arg(new Scalar\String_($url . '?%s'))], array_merge($replaceArgs, [new Expr\MethodCall($queryParamVariable, 'buildQueryString', [new Arg(new Expr\Variable('parameters'))])]))))]);
     $methodBody = array_merge($methodBody, [new Expr\Assign(new Expr\Variable('request'), new Expr\MethodCall(new Expr\PropertyFetch(new Expr\Variable('this'), 'messageFactory'), 'createRequest', [new Arg(new Scalar\String_($operation->getMethod())), new Arg(new Expr\Variable('url')), new Arg(new Expr\MethodCall($queryParamVariable, 'buildHeaders', [new Arg(new Expr\Variable('parameters'))])), new Arg($bodyParameter === null ? new Expr\ConstFetch(new Name('null')) : new Expr\Variable($bodyParameter->getName()))])), new Expr\Assign(new Expr\Variable('response'), new Expr\MethodCall(new Expr\PropertyFetch(new Expr\Variable('this'), 'httpClient'), 'sendRequest', [new Arg(new Expr\Variable('request'))])), new Stmt\If_(new Expr\BinaryOp\Equal(new Expr\ConstFetch(new Name('self::FETCH_RESPONSE')), new Expr\Variable('fetch')), ['stmts' => [new Stmt\Return_(new Expr\Variable('response'))]])]);
     foreach ($operation->getOperation()->getResponses() as $status => $response) {
         $ifStatus = $this->createResponseDenormalizationStatement($status, $response->getSchema(), $context);
         if (null !== $ifStatus) {
             $methodBody[] = $ifStatus;
         }
     }
     $methodBody[] = new Stmt\Return_(new Expr\Variable('response'));
     return new Stmt\ClassMethod($name, ['type' => Stmt\Class_::MODIFIER_PUBLIC, 'params' => $methodParameters, 'stmts' => $methodBody], ['comments' => [new Comment\Doc(implode("\n", $documentation))]]);
 }