package org.osbp.mysmartshop.dtos.mapper;

import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.mysmartshop.dtos.DtoTestChildCrossRefDto;
import org.osbp.mysmartshop.dtos.DtoTestParentDto;
import org.osbp.mysmartshop.dtos.mapper.BaseUUIDDtoMapper;
import org.osbp.mysmartshop.entities.DtoTestChildCrossRef;
import org.osbp.mysmartshop.entities.DtoTestParent;

/**
 * This class maps the dto {@link DtoTestChildCrossRefDto} to and from the entity {@link DtoTestChildCrossRef}.
 * 
 */
@SuppressWarnings("all")
public class DtoTestChildCrossRefDtoMapper<DTO extends DtoTestChildCrossRefDto, ENTITY extends DtoTestChildCrossRef> extends BaseUUIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public DtoTestChildCrossRef createEntity() {
    return new DtoTestChildCrossRef();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public DtoTestChildCrossRefDto createDto() {
    return new DtoTestChildCrossRefDto();
  }
  
  /**
   * Maps the entity {@link DtoTestChildCrossRef} to the dto {@link DtoTestChildCrossRefDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final DtoTestChildCrossRefDto dto, final DtoTestChildCrossRef entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    context.register(createDtoHash(entity), dto);
    
    super.mapToDTO(dto, entity, context);
    
    dto.setContainer(toDto_container(entity, context));
  }
  
  /**
   * Maps the dto {@link DtoTestChildCrossRefDto} to the entity {@link DtoTestChildCrossRef}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final DtoTestChildCrossRefDto dto, final DtoTestChildCrossRef entity, final MappingContext context) {
    if(context == null){
    	throw new IllegalArgumentException("Please pass a context!");
    }
    
    context.register(createEntityHash(dto), entity);
    context.registerMappingRoot(createEntityHash(dto), dto);
    super.mapToEntity(dto, entity, context);
    
    entity.setContainer(toEntity_container(dto, entity, context));
  }
  
  /**
   * Maps the property container 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 DtoTestParentDto toDto_container(final DtoTestChildCrossRef in, final MappingContext context) {
    if(in.getContainer() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestParentDto, DtoTestParent> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestParentDto, DtoTestParent>) getToDtoMapper(DtoTestParentDto.class, in.getContainer().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	DtoTestParentDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getContainer()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getContainer(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getContainer(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property container 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 DtoTestParent toEntity_container(final DtoTestChildCrossRefDto in, final DtoTestChildCrossRef parentEntity, final MappingContext context) {
    if(in.getContainer() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestParentDto, DtoTestParent> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestParentDto, DtoTestParent>) getToEntityMapper(in.getContainer().getClass(), DtoTestParent.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	DtoTestParent entity = null;
    	entity = context.get(mapper.createEntityHash(in.getContainer()));
    	if(entity != null) {
    		return entity;
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getContainer(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(DtoTestChildCrossRefDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(DtoTestChildCrossRef.class, in);
  }
}
