/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf), Loetz GmbH&Co.KG (Heidelberg)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */

package org.osbp.mysmartshop.dtos.mapper;

import org.eclipse.osbp.dsl.dto.lib.IMapper;
import org.eclipse.osbp.dsl.dto.lib.IMapperAccess;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.mysmartshop.dtos.DtoTestBeanDto;
import org.osbp.mysmartshop.dtos.DtoTestChildCrossRefDto;
import org.osbp.mysmartshop.entities.DtoTestBean;
import org.osbp.mysmartshop.entities.DtoTestChildCrossRef;

/**
 * This class maps the dto {@link DtoTestBeanDto} to and from the entity {@link DtoTestBean}.
 * 
 */
@SuppressWarnings("all")
public class DtoTestBeanDtoMapper<DTO extends DtoTestBeanDto, ENTITY extends DtoTestBean> implements IMapper<DTO, ENTITY> {
  private IMapperAccess mapperAccess;
  
  /**
   * Returns the mapper instance that may map between the given dto and entity. Or <code>null</code> if no mapper is available.
   * 
   * @param dtoClass - the class of the dto that should be mapped
   * @param entityClass - the class of the entity that should be mapped
   * @return the mapper instance or <code>null</code>
   */
  protected <D, E> IMapper<D, E> getToDtoMapper(final Class<D> dtoClass, final Class<E> entityClass) {
    return mapperAccess.getToDtoMapper(dtoClass, entityClass);
  }
  
  /**
   * Returns the mapper instance that may map between the given dto and entity. Or <code>null</code> if no mapper is available.
   * 
   * @param dtoClass - the class of the dto that should be mapped
   * @param entityClass - the class of the entity that should be mapped
   * @return the mapper instance or <code>null</code>
   */
  protected <D, E> IMapper<D, E> getToEntityMapper(final Class<D> dtoClass, final Class<E> entityClass) {
    return mapperAccess.getToEntityMapper(dtoClass, entityClass);
  }
  
  /**
   * Called by OSGi-DS. Binds the mapper access service.
   * 
   * @param service - The mapper access service
   * 
   */
  protected void bindMapperAccess(final IMapperAccess mapperAccess) {
    this.mapperAccess = mapperAccess;
  }
  
  /**
   * Called by OSGi-DS. Binds the mapper access service.
   * 
   * @param service - The mapper access service
   * 
   */
  protected void unbindMapperAccess(final IMapperAccess mapperAccess) {
    this.mapperAccess = null;
  }
  
  /**
   * Creates a new instance of the entity
   */
  public DtoTestBean createEntity() {
    return new DtoTestBean();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public DtoTestBeanDto createDto() {
    return new DtoTestBeanDto();
  }
  
  /**
   * Maps the entity {@link DtoTestBean} to the dto {@link DtoTestBeanDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final DtoTestBeanDto dto, final DtoTestBean entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    dto.setFoo(toDto_foo(entity, context));
    dto.setCrossRefChild(toDto_crossRefChild(entity, context));
  }
  
  /**
   * Maps the dto {@link DtoTestBeanDto} to the entity {@link DtoTestBean}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final DtoTestBeanDto dto, final DtoTestBean entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    
    
    entity.setFoo(toEntity_foo(dto, entity, context));
    entity.setCrossRefChild(toEntity_crossRefChild(dto, entity, context));
  }
  
  /**
   * Maps the property foo from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toDto_foo(final DtoTestBean in, final MappingContext context) {
    return in.getFoo();
  }
  
  /**
   * Maps the property foo from the given entity to dto property.
   * 
   * @param in - The source entity
   * @param parentEntity - The parentEntity
   * @param context - The context to get information about depth,...
   * @return the mapped value
   * 
   */
  protected String toEntity_foo(final DtoTestBeanDto in, final DtoTestBean parentEntity, final MappingContext context) {
    return in.getFoo();
  }
  
  /**
   * Maps the property crossRefChild from the given entity to the dto.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return the mapped dto
   * 
   */
  protected DtoTestChildCrossRefDto toDto_crossRefChild(final DtoTestBean in, final MappingContext context) {
    if(in.getCrossRefChild() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestChildCrossRefDto, DtoTestChildCrossRef> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestChildCrossRefDto, DtoTestChildCrossRef>) getToDtoMapper(DtoTestChildCrossRefDto.class, in.getCrossRefChild().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	DtoTestChildCrossRefDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getCrossRefChild()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getCrossRefChild(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getCrossRefChild(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property crossRefChild from the given dto to the entity.
   * 
   * @param in - The source dto
   * @param parentEntity - The parent entity
   * @param context - The context to get information about depth,...
   * @return the mapped entity
   * 
   */
  protected DtoTestChildCrossRef toEntity_crossRefChild(final DtoTestBeanDto in, final DtoTestBean parentEntity, final MappingContext context) {
    if(in.getCrossRefChild() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestChildCrossRefDto, DtoTestChildCrossRef> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestChildCrossRefDto, DtoTestChildCrossRef>) getToEntityMapper(in.getCrossRefChild().getClass(), DtoTestChildCrossRef.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	DtoTestChildCrossRef entity = null;
    	entity = context.get(mapper.createEntityHash(in.getCrossRefChild()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (DtoTestChildCrossRef) context
    			.findEntityByEntityManager(DtoTestChildCrossRef.class, in.getCrossRefChild().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getCrossRefChild()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getCrossRefChild(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  public String createDtoHash(final Object in) {
    throw new UnsupportedOperationException("No id attribute available");
  }
  
  public String createEntityHash(final Object in) {
    throw new UnsupportedOperationException("No id attribute available");
  }
}
