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.CompanyGroupDto;
import org.osbp.mysmartshop.dtos.CompanyRelationTypeDto;
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.CompanyGroup;
import org.osbp.mysmartshop.entities.CompanyRelationType;
import org.osbp.mysmartshop.entities.Department;

/**
 * This class maps the dto {@link CompanyDto} to and from the entity {@link Company}.
 * 
 */
@SuppressWarnings("all")
public class CompanyDtoMapper<DTO extends CompanyDto, ENTITY extends Company> extends BaseUUIDDtoMapper<DTO, ENTITY> {
  /**
   * Creates a new instance of the entity
   */
  public Company createEntity() {
    return new Company();
  }
  
  /**
   * Creates a new instance of the dto
   */
  public CompanyDto createDto() {
    return new CompanyDto();
  }
  
  /**
   * Maps the entity {@link Company} to the dto {@link CompanyDto}.
   * 
   * @param dto - The target dto
   * @param entity - The source entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToDTO(final CompanyDto dto, final Company 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_group(toDto_company_group(entity, context));
    dto.setName(toDto_name(entity, context));
    dto.setDescription(toDto_description(entity, context));
    dto.setRelation_type(toDto_relation_type(entity, context));
  }
  
  /**
   * Maps the dto {@link CompanyDto} to the entity {@link Company}.
   * 
   * @param dto - The source dto
   * @param entity - The target entity
   * @param context - The context to get information about depth,...
   * 
   */
  public void mapToEntity(final CompanyDto dto, final Company 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_group(toEntity_company_group(dto, entity, context));
    entity.setName(toEntity_name(dto, entity, context));
    entity.setDescription(toEntity_description(dto, entity, context));
    entity.setRelation_type(toEntity_relation_type(dto, entity, context));
    toEntity_address(dto, entity, context);
    toEntity_departments(dto, entity, context);
  }
  
  /**
   * Maps the property company_group 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 CompanyGroupDto toDto_company_group(final Company in, final MappingContext context) {
    if(in.getCompany_group() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyGroupDto, CompanyGroup> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyGroupDto, CompanyGroup>) getToDtoMapper(CompanyGroupDto.class, in.getCompany_group().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CompanyGroupDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getCompany_group()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getCompany_group(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getCompany_group(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property company_group 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 CompanyGroup toEntity_company_group(final CompanyDto in, final Company parentEntity, final MappingContext context) {
    if(in.getCompany_group() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyGroupDto, CompanyGroup> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyGroupDto, CompanyGroup>) getToEntityMapper(in.getCompany_group().getClass(), CompanyGroup.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	CompanyGroup entity = null;
    	entity = context.get(mapper.createEntityHash(in.getCompany_group()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (CompanyGroup) context
    			.findEntityByEntityManager(CompanyGroup.class, in.getCompany_group().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getCompany_group()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getCompany_group(), 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 Company 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 CompanyDto in, final Company 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 Company 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 CompanyDto in, final Company parentEntity, final MappingContext context) {
    return in.getDescription();
  }
  
  /**
   * Maps the property relation_type 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 CompanyRelationTypeDto toDto_relation_type(final Company in, final MappingContext context) {
    if(in.getRelation_type() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyRelationTypeDto, CompanyRelationType> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyRelationTypeDto, CompanyRelationType>) getToDtoMapper(CompanyRelationTypeDto.class, in.getRelation_type().getClass());
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    	CompanyRelationTypeDto dto = null;
    	dto = context.get(mapper.createDtoHash(in.getRelation_type()));
    	if(dto != null) {
    		if(context.isRefresh()){
    			mapper.mapToDTO(dto, in.getRelation_type(), context);
    		}
    		return dto;
    	}
    	
    	context.increaseLevel();
    	dto = mapper.createDto();
    	mapper.mapToDTO(dto, in.getRelation_type(), context);
    	context.decreaseLevel();
    	return dto;
    } else {
    	return null;
    }
  }
  
  /**
   * Maps the property relation_type 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 CompanyRelationType toEntity_relation_type(final CompanyDto in, final Company parentEntity, final MappingContext context) {
    if(in.getRelation_type() != null) {
    	// find a mapper that knows how to map the concrete input type.
    	org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyRelationTypeDto, CompanyRelationType> mapper = (org.eclipse.osbp.dsl.dto.lib.IMapper<CompanyRelationTypeDto, CompanyRelationType>) getToEntityMapper(in.getRelation_type().getClass(), CompanyRelationType.class);
    	if(mapper == null) {
    		throw new IllegalStateException("Mapper must not be null!");
    	}
    
    	CompanyRelationType entity = null;
    	entity = context.get(mapper.createEntityHash(in.getRelation_type()));
    	if(entity != null) {
    		return entity;
    	} else {
    		entity = (CompanyRelationType) context
    			.findEntityByEntityManager(CompanyRelationType.class, in.getRelation_type().getId());
    		if (entity != null) {
    			context.register(mapper.createEntityHash(in.getRelation_type()), entity);
    			return entity;
    		}
    	}
    
    	entity = mapper.createEntity();
    	mapper.mapToEntity(in.getRelation_type(), entity, context);	
    	return entity;
    } else {
    	return null;
    }	
  }
  
  /**
   * 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 Company 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 CompanyDto in, final Company 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 departments 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<DepartmentDto> toDto_departments(final Company in, final MappingContext context) {
    // nothing to do here. Mapping is done by OppositeLists
    return null;
  }
  
  /**
   * Maps the property departments 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<Department> toEntity_departments(final CompanyDto in, final Company parentEntity, final MappingContext context) {
    org.eclipse.osbp.dsl.dto.lib.IMapper<DepartmentDto, Department> mapper = getToEntityMapper(DepartmentDto.class, Department.class);
    if(mapper == null) {
    	throw new IllegalStateException("Mapper must not be null!");
    }
    
    org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<DepartmentDto> childsList = 
    	(org.eclipse.osbp.dsl.dto.lib.IEntityMappingList<DepartmentDto>) in.internalGetDepartments();
    
    // 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::addToDepartments,
    		parentEntity::internalRemoveFromDepartments);
    return null;
  }
  
  public String createDtoHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(CompanyDto.class, in);
  }
  
  public String createEntityHash(final Object in) {
    return org.eclipse.osbp.runtime.common.hash.HashUtil.createObjectWithIdHash(Company.class, in);
  }
}
