/**
  * Builds ApiDoc annotation from DunglasApiBundle data.
  *
  * @param bool               $collection
  * @param ResourceInterface  $resource
  * @param OperationInterface $operation
  * @param array              $resourceHydraDoc
  * @param array              $entrypointHydraDoc
  *
  * @return ApiDoc
  */
 private function getApiDoc($collection, ResourceInterface $resource, OperationInterface $operation, array $resourceHydraDoc, array $entrypointHydraDoc = [])
 {
     $method = $operation->getRoute()->getMethods()[0];
     if ($collection) {
         $operationHydraDoc = $this->getCollectionOperationHydraDoc($resource->getShortName(), $method, $entrypointHydraDoc);
     } else {
         $operationHydraDoc = $this->getOperationHydraDoc($operation->getRoute()->getMethods()[0], $resourceHydraDoc);
     }
     $route = $operation->getRoute();
     $data = ['resource' => $route->getPath(), 'description' => $operationHydraDoc['hydra:title'], 'resourceDescription' => $resourceHydraDoc['hydra:title'], 'section' => $resourceHydraDoc['hydra:title']];
     $entityClass = $resource->getEntityClass();
     if (isset($operationHydraDoc['expects']) && 'owl:Nothing' !== $operationHydraDoc['expects']) {
         $data['input'] = sprintf('%s:%s', DunglasApiParser::IN_PREFIX, $entityClass);
     }
     if (isset($operationHydraDoc['returns']) && 'owl:Nothing' !== $operationHydraDoc['returns']) {
         $data['output'] = sprintf('%s:%s', DunglasApiParser::OUT_PREFIX, $entityClass);
     }
     if (Request::METHOD_GET === $method && $collection) {
         $data['filters'] = [];
         foreach ($resource->getFilters() as $filter) {
             foreach ($filter->getDescription($resource) as $name => $definition) {
                 $data['filters'][] = ['name' => $name] + $definition;
             }
         }
     }
     $apiDoc = new ApiDoc($data);
     $apiDoc->setRoute($route);
     return $apiDoc;
 }
 /**
  * Gets and populates if applicable a Hydra operation.
  *
  * @param ResourceInterface  $resource
  * @param OperationInterface $operation
  * @param string             $prefixedShortName
  * @param bool               $collection
  *
  * @return array
  */
 private function getHydraOperation(ResourceInterface $resource, OperationInterface $operation, $prefixedShortName, $collection)
 {
     $method = $operation->getRoute()->getMethods();
     if (is_array($method)) {
         $method = $method[0];
     }
     $hydraOperation = $operation->getContext();
     switch ($method) {
         case 'GET':
             if ($collection) {
                 if (!isset($hydraOperation['hydra:title'])) {
                     $hydraOperation['hydra:title'] = sprintf('Retrieves the collection of %s resources.', $resource->getShortName());
                 }
                 if (!isset($hydraOperation['returns'])) {
                     $hydraOperation['returns'] = 'hydra:PagedCollection';
                 }
             } else {
                 if (!isset($hydraOperation['hydra:title'])) {
                     $hydraOperation['hydra:title'] = sprintf('Retrieves %s resource.', $resource->getShortName());
                 }
             }
             break;
         case 'POST':
             if (!isset($hydraOperation['@type'])) {
                 $hydraOperation['@type'] = 'hydra:CreateResourceOperation';
             }
             if (!isset($hydraOperation['hydra:title'])) {
                 $hydraOperation['hydra:title'] = sprintf('Creates a %s resource.', $resource->getShortName());
             }
             break;
         case 'PUT':
             if (!isset($hydraOperation['@type'])) {
                 $hydraOperation['@type'] = 'hydra:ReplaceResourceOperation';
             }
             if (!isset($hydraOperation['hydra:title'])) {
                 $hydraOperation['hydra:title'] = sprintf('Replaces the %s resource.', $resource->getShortName());
             }
             break;
         case 'DELETE':
             if (!isset($hydraOperation['hydra:title'])) {
                 $hydraOperation['hydra:title'] = sprintf('Deletes the %s resource.', $resource->getShortName());
             }
             if (!isset($hydraOperation['returns'])) {
                 $hydraOperation['returns'] = 'owl:Nothing';
             }
             break;
     }
     if (!isset($hydraOperation['returns']) && ('GET' === $method && !$collection || 'POST' === $method || 'PUT' === $method)) {
         $hydraOperation['returns'] = $prefixedShortName;
     }
     if (!isset($hydraOperation['expects']) && ('POST' === $method || 'PUT' === $method)) {
         $hydraOperation['expects'] = $prefixedShortName;
     }
     if (!isset($hydraOperation['@type'])) {
         $hydraOperation['@type'] = 'hydra:Operation';
     }
     if (!isset($hydraOperation['hydra:method'])) {
         $hydraOperation['hydra:method'] = $method;
     }
     if (!isset($hydraOperation['rdfs:label']) && isset($hydraOperation['hydra:title'])) {
         $hydraOperation['rdfs:label'] = $hydraOperation['hydra:title'];
     }
     ksort($hydraOperation);
     return $hydraOperation;
 }
 /**
  * Gets and populates if applicable a Hydra operation.
  *
  * @param ResourceInterface  $resource
  * @param OperationInterface $operation
  * @param string             $prefixedShortName
  * @param bool               $collection
  *
  * @return array
  */
 protected function getHydraOperation(ResourceInterface $resource, OperationInterface $operation, $prefixedShortName, $collection)
 {
     $method = $operation->getRoute()->getMethods();
     if (is_array($method)) {
         // If all methods are allowed, default to GET
         $method = isset($method[0]) ? $method[0] : 'GET';
     }
     $methodDoc = $this->documentationHelper->getReflectionMethod($operation->getRoute()->getDefault('_controller'));
     $annotation = $methodDoc !== null ? $this->documentationHelper->getMethodAnnotation($methodDoc) : null;
     $hydraOperation = $operation->getContext();
     $hydraOperation['hydra:entrypoint'] = $operation->getRoute()->getPath();
     switch ($method) {
         case 'GET':
             if ($collection) {
                 if (!isset($hydraOperation['hydra:title'])) {
                     $hydraOperation['hydra:title'] = sprintf('Retrieves the collection of %s resources.', $resource->getShortName());
                 }
                 if (!isset($hydraOperation['returns'])) {
                     $hydraOperation['returns'] = 'hydra:PagedCollection';
                 }
                 foreach ($resource->getFilters() as $filter) {
                     foreach ($filter->getDescription($resource) as $key => $value) {
                         $hydraOperation["hydra:search"][$key] = ['requirement' => '[a-zA-Z0-9-]+', 'description' => $key . ' filter', 'default' => ''];
                     }
                 }
             } else {
                 if (!isset($hydraOperation['hydra:title'])) {
                     $hydraOperation['hydra:title'] = null !== $annotation && null !== $annotation->getDescription() ? $annotation->getDescription() : sprintf('Retrieves %s resource.', $resource->getShortName());
                 }
                 if (null !== $annotation) {
                     $hydraOperation['returns'] = $annotation->getOutput();
                 }
             }
             break;
         case 'POST':
             if (!isset($hydraOperation['@type'])) {
                 $hydraOperation['@type'] = 'hydra:CreateResourceOperation';
             }
             if (!isset($hydraOperation['hydra:title'])) {
                 $hydraOperation['hydra:title'] = sprintf('Creates a %s resource.', $resource->getShortName());
             }
             break;
         case 'PUT':
             if (!isset($hydraOperation['@type'])) {
                 $hydraOperation['@type'] = 'hydra:ReplaceResourceOperation';
             }
             if (!isset($hydraOperation['hydra:title'])) {
                 $hydraOperation['hydra:title'] = sprintf('Replaces the %s resource.', $resource->getShortName());
             }
             break;
         case 'DELETE':
             if (!isset($hydraOperation['hydra:title'])) {
                 $hydraOperation['hydra:title'] = sprintf('Deletes the %s resource.', $resource->getShortName());
             }
             if (!isset($hydraOperation['returns'])) {
                 $hydraOperation['returns'] = 'owl:Nothing';
             }
             break;
     }
     if (!isset($hydraOperation['returns']) && ('GET' === $method && !$collection || 'POST' === $method || 'PUT' === $method)) {
         $hydraOperation['returns'] = $prefixedShortName;
     }
     if (!isset($hydraOperation['expects']) && ('POST' === $method || 'PUT' === $method)) {
         $hydraOperation['expects'] = $prefixedShortName;
     }
     if (!isset($hydraOperation['@type'])) {
         $hydraOperation['@type'] = 'hydra:Operation';
     }
     if (!isset($hydraOperation['hydra:method'])) {
         $hydraOperation['hydra:method'] = $method;
     }
     if (!isset($hydraOperation['rdfs:label']) && isset($hydraOperation['hydra:title'])) {
         $hydraOperation['rdfs:label'] = $hydraOperation['hydra:title'];
     }
     ksort($hydraOperation);
     return $hydraOperation;
 }