package org.osbp.mysmartshop.dtos.mapper;

import java.util.List;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.osbp.mysmartshop.dtos.AddressDto;
import org.osbp.mysmartshop.dtos.CompanyDto;
import org.osbp.mysmartshop.dtos.DepartmentDto;
import org.osbp.mysmartshop.dtos.mapper.BaseUUIDDtoMapper;
import org.osbp.mysmartshop.entities.Address;
import org.osbp.mysmartshop.entities.Company;
import org.osbp.mysmartshop.entities.Department;

/**
 * This class maps the dto {@link DepartmentDto} to and from the entity {@link Department}.
 * 
 */
@SuppressWarnings("all")
public class DepartmentDtoMapper<DTO extends DepartmentDto, ENTITY extends Department> extends BaseUUIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public Department createEntity() {
    return new Department();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public DepartmentDto createDto() {
    return new DepartmentDto();
  }
  
  /**
   * Maps the entity {@link Department} to the dto {@link DepartmentDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final DepartmentDto dto, final Department 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.setCompany(toDto_company(entity, context));
    dto.setName(toDto_name(entity, context));
    dto.setDescription(toDto_description(entity, context));
    dto.setDefault_yearly_income(toDto_default_yearly_income(entity, context));
  }
  
  /**
   * Maps the dto {@link DepartmentDto} to the entity {@link Department}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final DepartmentDto dto, final Department 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.setCompany(toEntity_company(dto, entity, context));
    entity.setName(toEntity_name(dto, entity, context));
    entity.setDescription(toEntity_description(dto, entity, context));
    toEntity_address(dto, entity, context);
    entity.setDefault_yearly_income(toEntity_default_yearly_income(dto, entity, context));
  }
  
  /**
   * Maps the property company 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 CompanyDto toDto_company(final Department in, final MappingContext context) {
    if(in.getCompany() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company>) getToDtoMapper(CompanyDto.class, in.getCompany().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CompanyDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getCompany()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getCompany(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getCompany(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property company 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 Company toEntity_company(final DepartmentDto in, final Department parentEntity, final MappingContext context) {
    if(in.getCompany() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyDto, Company>) getToEntityMapper(in.getCompany().getClass(), Company.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	Company entity = null;
    	entity = context.get(mapper.createEntityHash(in.getCompany()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (Company) context
    			.findEntityByEntityManager(Company.class, in.getCompany().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getCompany()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getCompany(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * Maps the property name 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_name(final Department in, final MappingContext context) {
    return in.getName();
  }
  
  /**
   * Maps the property name 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_name(final DepartmentDto in, final Department parentEntity, final MappingContext context) {
    return in.getName();
  }
  
  /**
   * Maps the property description 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_description(final Department in, final MappingContext context) {
    return in.getDescription();
  }
  
  /**
   * Maps the property description 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_description(final DepartmentDto in, final Department parentEntity, final MappingContext context) {
    return in.getDescription();
  }
  
  /**
   * Maps the property address 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<AddressDto> toDto_address(final Department in, final MappingContext context) {
    // nothing to do here. Mapping is done by OppositeLists
    return null;
  }
  
  /**
   * Maps the property address 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<Address> toEntity_address(final DepartmentDto in, final Department parentEntity, final MappingContext context) {
    org.eclipse.osbp.dsl.dto.lib.IMapper<AddressDto, Address> mapper = getToEntityMapper(AddressDto.class, Address.class);
    if(mapper == null) {
    	throw new IllegalStateException("Mapper must not be null!");
    }
    
    org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<AddressDto> childsList = 
    	(org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<AddressDto>) in.internalGetAddress();
    
    // 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::addToAddress,
    		parentEntity::internalRemoveFromAddress);
    return null;
  }
  
  /**
   * Maps the property default_yearly_income 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 double toDto_default_yearly_income(final Department in, final MappingContext context) {
    return in.getDefault_yearly_income();
  }
  
  /**
   * Maps the property default_yearly_income 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 double toEntity_default_yearly_income(final DepartmentDto in, final Department parentEntity, final MappingContext context) {
    return in.getDefault_yearly_income();
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(DepartmentDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(Department.class, in);
  }
}
