package org.osbp.mysmartshop.dtos.mapper;

import java.util.List;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.mysmartshop.dtos.DtoTestBeanDto;
import org.osbp.mysmartshop.dtos.DtoTestChildContainmentDto;
import org.osbp.mysmartshop.dtos.DtoTestChildCrossRefDto;
import org.osbp.mysmartshop.dtos.DtoTestParentDto;
import org.osbp.mysmartshop.dtos.mapper.BaseUUIDDtoMapper;
import org.osbp.mysmartshop.entities.DtoTestBean;
import org.osbp.mysmartshop.entities.DtoTestChildContainment;
import org.osbp.mysmartshop.entities.DtoTestChildCrossRef;
import org.osbp.mysmartshop.entities.DtoTestParent;

/**
 * This class maps the dto {@link DtoTestParentDto} to and from the entity {@link DtoTestParent}.
 * 
 */
@SuppressWarnings("all")
public class DtoTestParentDtoMapper<DTO extends DtoTestParentDto, ENTITY extends DtoTestParent> extends BaseUUIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public DtoTestParent createEntity() {
    return new DtoTestParent();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public DtoTestParentDto createDto() {
    return new DtoTestParentDto();
  }
  
  /**
   * Maps the entity {@link DtoTestParent} to the dto {@link DtoTestParentDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final DtoTestParentDto dto, final DtoTestParent 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.setString(toDto_string(entity, context));
    dto.setCrossRefChild(toDto_crossRefChild(entity, context));
    dto.setBeanx(toDto_beanx(entity, context));
  }
  
  /**
   * Maps the dto {@link DtoTestParentDto} to the entity {@link DtoTestParent}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final DtoTestParentDto dto, final DtoTestParent 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.setString(toEntity_string(dto, entity, context));
    toEntity_containmentChilds(dto, entity, context);
    toEntity_crossRefChilds(dto, entity, context);
    entity.setCrossRefChild(toEntity_crossRefChild(dto, entity, context));
    entity.setBeanx(toEntity_beanx(dto, entity, context));
  }
  
  /**
   * Maps the property string 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_string(final DtoTestParent in, final MappingContext context) {
    return in.getString();
  }
  
  /**
   * Maps the property string 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_string(final DtoTestParentDto in, final DtoTestParent parentEntity, final MappingContext context) {
    return in.getString();
  }
  
  /**
   * Maps the property containmentChilds from the given entity to the dto.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return A list of mapped dtos
   * 
   */
  protected List<DtoTestChildContainmentDto> toDto_containmentChilds(final DtoTestParent in, final MappingContext context) {
    // nothing to do here. Mapping is done by OppositeLists
    return null;
  }
  
  /**
   * Maps the property containmentChilds 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 A list of mapped entities
   * 
   */
  protected List<DtoTestChildContainment> toEntity_containmentChilds(final DtoTestParentDto in, final DtoTestParent parentEntity, final MappingContext context) {
    org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestChildContainmentDto, DtoTestChildContainment> mapper = getToEntityMapper(DtoTestChildContainmentDto.class, DtoTestChildContainment.class);
    if(mapper == null) {
    	throw new IllegalStateException("Mapper must not be null!");
    }
    
    org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<DtoTestChildContainmentDto> childsList = 
    	(org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<DtoTestChildContainmentDto>) in.internalGetContainmentChilds();
    
    // if entities are being added, then they are passed to
    // #addToContainerChilds of the parent entity. So the container ref is setup
    // properly!
    // if entities are being removed, then they are passed to the
    // #internalRemoveFromChilds method of the parent entity. So they are
    // removed directly from the list of entities.
    childsList.mapToEntity(mapper,
    		parentEntity::addToContainmentChilds,
    		parentEntity::internalRemoveFromContainmentChilds);
    return null;
  }
  
  /**
   * Maps the property crossRefChilds from the given entity to the dto.
   * 
   * @param in - The source entity
   * @param context - The context to get information about depth,...
   * @return A list of mapped dtos
   * 
   */
  protected List<DtoTestChildCrossRefDto> toDto_crossRefChilds(final DtoTestParent in, final MappingContext context) {
    // nothing to do here. Mapping is done by OppositeLists
    return null;
  }
  
  /**
   * Maps the property crossRefChilds 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 A list of mapped entities
   * 
   */
  protected List<DtoTestChildCrossRef> toEntity_crossRefChilds(final DtoTestParentDto in, final DtoTestParent parentEntity, final MappingContext context) {
    org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestChildCrossRefDto, DtoTestChildCrossRef> mapper = getToEntityMapper(DtoTestChildCrossRefDto.class, DtoTestChildCrossRef.class);
    if(mapper == null) {
    	throw new IllegalStateException("Mapper must not be null!");
    }
    
    org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<DtoTestChildCrossRefDto> childsList = 
    	(org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<DtoTestChildCrossRefDto>) in.internalGetCrossRefChilds();
    
    // if entities are being added, then they are passed to
    // #addToContainerChilds of the parent entity. So the container ref is setup
    // properly!
    // if entities are being removed, then they are passed to the
    // #internalRemoveFromChilds method of the parent entity. So they are
    // removed directly from the list of entities.
    childsList.mapToEntity(mapper,
    		parentEntity::addToCrossRefChilds,
    		parentEntity::internalRemoveFromCrossRefChilds);
    return null;
  }
  
  /**
   * 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 DtoTestParent 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 DtoTestParentDto in, final DtoTestParent 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;
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getCrossRefChild(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * Maps the property beanx 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 DtoTestBeanDto toDto_beanx(final DtoTestParent in, final MappingContext context) {
    if(in.getBeanx() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestBeanDto, DtoTestBean> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestBeanDto, DtoTestBean>) getToDtoMapper(DtoTestBeanDto.class, in.getBeanx().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	DtoTestBeanDto dto = null;
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getBeanx(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property beanx 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 DtoTestBean toEntity_beanx(final DtoTestParentDto in, final DtoTestParent parentEntity, final MappingContext context) {
    if(in.getBeanx() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestBeanDto, DtoTestBean> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<DtoTestBeanDto, DtoTestBean>) getToEntityMapper(in.getBeanx().getClass(), DtoTestBean.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	DtoTestBean entity = mapper.createEntity();
    	mapper.mapToEntity(in.getBeanx(), entity, context);
    	return entity;							
    } else {
    	return null;
    }
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(DtoTestParentDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(DtoTestParent.class, in);
  }
}
