package com.airlock.iam.common.infrastructure.mapper;

import java.util.Optional;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.converter.BidirectionalConverter;
import ma.glasnost.orika.metadata.Type;

public final class OptionalConverter<S, T> extends BidirectionalConverter<S, Optional<T>> {
   public S convertFrom(Optional<T> optional, Type<S> targetType, MappingContext mappingContext) {
      T value = optional.orElse(null);
      return (S)this.mapperFacade.map(value, targetType.getRawType());
   }

   public Optional<T> convertTo(S value, Type<Optional<T>> optionalType, MappingContext mappingContext) {
      T optionalValue = (T)this.mapperFacade.map(value, optionalType.getNestedType(0).getRawType());
      return Optional.ofNullable(optionalValue);
   }

   public boolean canConvert(Type<?> sourceType, Type<?> destinationType) {
      return (this.isOptional(sourceType) || this.isOptional(destinationType)) && (!this.isOptional(sourceType) || !this.isOptional(destinationType));
   }

   private boolean isOptional(Type<?> type) {
      return type.getRawType().equals(Optional.class);
   }
}
