package org.eclipse.osbp.dsl.dto.lib.services.impl;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import javax.persistence.LockModeType;

import org.eclipse.osbp.jpa.services.filters.LAnd;
import org.eclipse.osbp.jpa.services.filters.LCompare;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.filter.IJPQL;
import org.eclipse.osbp.runtime.common.filter.ILFilter;
import org.eclipse.osbp.runtime.common.filter.IQuery;

public abstract class AbstractDTOHistorizedService<DTO, ENTITY> extends AbstractDTOService<DTO, ENTITY> 
	implements org.eclipse.osbp.runtime.common.filter.IDTOHistorizedService<DTO> {

	protected boolean ignoreHistorizedFilter = false;
	
	public boolean isIgnoreHistorizedFilter() {
		return ignoreHistorizedFilter;
	}

	public void setIgnoreHistorizedFilter(boolean ignoreHistorizedFilter) {
		this.ignoreHistorizedFilter = ignoreHistorizedFilter;
	}

	@Override
	public DTO get(final Object id, Object ui, LockModeType lockModeType) {
		DTO dto = super.get(id, ui, lockModeType);
		if(dto != null && DtoUtils.isHistCurrent(dto)) {
			return dto;
		}
		return null;
	}

	@Override
	public DTO get(final Object id) {
		DTO dto = super.get(id);
		if(dto != null && DtoUtils.isHistCurrent(dto)) {
			return dto;
		}
		return null;
	}
	
	private List<DTO> filterHistCollection(Collection<DTO> collection) {
		return collection.stream().filter(dto->dto != null && (ignoreHistorizedFilter || DtoUtils.isHistCurrent(dto))).collect(Collectors.toList());
//		List<DTO> result = new ArrayList<DTO>();
//		for(DTO dto:collection) {
//			if(dto != null && DtoUtils.isHistCurrent(dto)) {
//				result.add(dto);
//			}
//		}
//		return result;
	}
	
	@Override
	public Collection<DTO> find(IQuery query, Object ui, LockModeType lockModeType) {
		return filterHistCollection(super.find(query, ui, lockModeType));
	}

	@Override
	public Collection<DTO> find(IQuery query) {
		return filterHistCollection(super.find(query));
	}

	@Override
	public Collection<DTO> find(IQuery query, int startIndex, Object ui, LockModeType lockModeType) {
		return filterHistCollection(super.find(query, startIndex, ui, lockModeType));
	}

	@Override
	public Collection<DTO> find(IQuery query, int startIndex) {
		return filterHistCollection(super.find(query, startIndex));
	}

	@Override
	public Collection<DTO> findDtos(IJPQL jpql) {
		return filterHistCollection(super.findDtos(jpql));
	}

	private IQuery filterHistQuery(IQuery query) {
		if(ignoreHistorizedFilter) {
			return query;
		}
		Field currentHistField = DtoUtils.getHistCurrentField(getDtoClass());
		ILFilter histFilter = new LCompare.Equal(currentHistField.getName(), 1);
		ILFilter filter = query.getFilter();
		if (filter == null) {
			query.replaceFilter(histFilter);
		}
		else {
			query.replaceFilter(new LAnd(histFilter, filter));
		}
		return query;
	}
	
	@Override
	public int size(IQuery query) {
		return super.size(filterHistQuery(query));
	}

	@Override
	public int size(IQuery query, Object ui, LockModeType lockModeType) {
		return super.size(filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public boolean contains(Object dto, IQuery query) {
		return super.contains(dto, filterHistQuery(query));
	}

	@Override
	public boolean contains(Object dto, IQuery query, Object ui, LockModeType lockModeType) {
		return super.contains(dto, filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public boolean contains(IQuery query) {
		return super.contains(filterHistQuery(query));
	}

	@Override
	public boolean contains(IQuery query, Object ui, LockModeType lockModeType) {
		return super.contains(filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public DTO getNext(DTO dto, IQuery query) {
		return super.getNext(dto, filterHistQuery(query));
	}

	@Override
	public DTO getNext(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
		return super.getNext(dto, filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public DTO getPrevious(DTO dto, IQuery query) {
		return super.getPrevious(dto, filterHistQuery(query));
	}

	@Override
	public DTO getPrevious(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
		return super.getNext(dto, filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public DTO getFirst(IQuery query) {
		return super.getFirst(filterHistQuery(query));
	}

	@Override
	public DTO getFirst(IQuery query, Object ui, LockModeType lockModeType) {
		return super.getFirst(filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public DTO getLast(IQuery query) {
		return super.getLast(filterHistQuery(query));
	}

	@Override
	public DTO getLast(IQuery query, Object ui, LockModeType lockModeType) {
		return super.getLast(filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public boolean isFirst(DTO dto, IQuery query) {
		return super.isFirst(dto, filterHistQuery(query));
	}

	@Override
	public boolean isFirst(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
		return super.isFirst(dto, filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public boolean isLast(DTO dto, IQuery query) {
		return super.isLast(dto, filterHistQuery(query));
	}

	@Override
	public boolean isLast(DTO dto, IQuery query, Object ui, LockModeType lockModeType) {
		return super.isLast(dto, filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public int indexOf(DTO dto, IQuery query) {
		return super.indexOf(dto, filterHistQuery(query));
	}

	@Override
	public DTO getByIndex(int index, IQuery query) {
		return super.getByIndex(index, filterHistQuery(query));
	}

	@Override
	public DTO getByIndex(int index, IQuery query, Object ui, LockModeType lockModeType) {
		return super.getByIndex(index, filterHistQuery(query), ui, lockModeType);
	}

	@Override
	public List<DTO> getByIndex(int startIndex, int numberOfItems, IQuery query) {
		return super.getByIndex(startIndex, numberOfItems, filterHistQuery(query));
	}

	@Override
	public List<DTO> getByIndex(int startIndex, int numberOfItems, IQuery query, Object ui, LockModeType lockModeType) {
		return super.getByIndex(startIndex, numberOfItems, filterHistQuery(query), ui, lockModeType);
	}

	/**
	 * Enhance filter.
	 *
	 * @param query
	 *            the query
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected void enhanceFilter(IQuery query) {
		super.enhanceFilter(filterHistQuery(query));
	}

}
