package com.airlock.iam.base.infrastructure.mapper.jsonapi;

import ch.ergon.restal.jsonapi.document.data.CollectionDocument;
import ch.ergon.restal.jsonapi.document.data.ResourceObject;
import com.airlock.iam.base.infrastructure.mapper.entity.IdSupplier;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MappingContext;

public final class JsonApiCollectionMapper<T, R> implements JsonApiMapper<T, R> {
   private final Collection<T> multipleElements;
   private final JsonApiResourceMapper<T, R> resourceMapper;

   public JsonApiCollectionMapper(MapperFacade orikaMapper, Collection<T> multipleElements, Class<R> targetType) {
      this.resourceMapper = new JsonApiResourceMapper<>(orikaMapper, targetType);
      this.multipleElements = multipleElements;
   }

   public JsonApiCollectionMapper<T, R> withIdSupplier(IdSupplier<T> supplier) {
      this.resourceMapper.withIdSupplier(supplier);
      return this;
   }

   public JsonApiCollectionMapper<T, R> withMappingContext(MappingContext context) {
      this.resourceMapper.withMappingContext(context);
      return this;
   }

   public CollectionDocument<R> toCollection() {
      List<ResourceObject<R>> resourceObjects = this.multipleElements
         .stream()
         .map(entity -> this.resourceMapper.toResourceObject((T)entity))
         .collect(Collectors.toList());
      return toCollection(resourceObjects);
   }

   private static <R> CollectionDocument<R> toCollection(List<ResourceObject<R>> resourceObjects) {
      CollectionDocument<R> document = new CollectionDocument();
      resourceObjects.forEach(document::add);
      return document;
   }
}
