/**
  * Use League\Csv\Reader to fetch data from csv file
  *
  * The reader checks if the first row of the file is the header row otherwise it uses the property names
  * of the prototype item to match columns. In this case the order in the file must be the same as defined in the prototype item.
  * The second scenario should be avoided because it can lead to silent errors.
  *
  * @param string $filename
  * @param Prototype $prototype
  * @param array $metadata
  * @throws \InvalidArgumentException
  * @return array
  */
 public function readDataForType($filename, Prototype $prototype, array &$metadata = [])
 {
     if ($prototype->typeDescription()->nativeType() !== NativeType::COLLECTION) {
         throw new \InvalidArgumentException('The CsvReader can only handle collections');
     }
     $itemPrototype = $prototype->typeProperties()['item']->typePrototype();
     $propertyNames = array_keys($itemPrototype->typeProperties());
     $reader = Reader::createFromPath($filename);
     if (array_key_exists('delimiter', $metadata)) {
         $reader->setDelimiter($metadata['delimiter']);
     }
     if (array_key_exists('enclosure', $metadata)) {
         $reader->setEnclosure($metadata['enclosure']);
     }
     if (array_key_exists('escape', $metadata)) {
         $reader->setEscape($metadata['escape']);
     }
     if (array_key_exists('file_encoding', $metadata)) {
         $reader->setEncodingFrom($metadata['file_encoding']);
     }
     $firstRow = $reader->fetchOne();
     $offset_or_keys = 0;
     $iteratorFilters = [];
     if ($this->isValidKeysRow($firstRow, $propertyNames)) {
         $iteratorFilters[] = function ($row, $rowIndex) {
             return $rowIndex != 0;
         };
     } else {
         $offset_or_keys = $propertyNames;
     }
     //Filter empty rows
     $iteratorFilters[] = function ($row) {
         if (!is_array($row)) {
             return false;
         }
         if (empty($row)) {
             return false;
         }
         if (count($row) === 1) {
             $value = current($row);
             return !empty($value);
         }
         return true;
     };
     foreach ($iteratorFilters as $iteratorFilter) {
         $reader->addFilter($iteratorFilter);
     }
     $metadata['total_items'] = $reader->each(function () {
         return true;
     });
     if (array_key_exists('offset', $metadata)) {
         $reader->setOffset($metadata['offset']);
     }
     if (array_key_exists('limit', $metadata)) {
         $reader->setLimit($metadata['limit']);
     }
     foreach ($iteratorFilters as $iteratorFilter) {
         $reader->addFilter($iteratorFilter);
     }
     return array_map(function ($row) use($itemPrototype) {
         return $this->convertToItemData($row, $itemPrototype);
     }, $reader->fetchAssoc($offset_or_keys));
 }