package com.eactive.eai.rms.data.entity.onl.adapter;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.data.entity.onl.adapter.Adapter;
import com.eactive.eai.data.entity.onl.adapter.AdapterId;
import com.eactive.eai.data.entity.onl.adapter.QAdapter;
import com.eactive.eai.data.entity.onl.adapter.QAdapterGroup;
import com.eactive.eai.data.entity.onl.adapter.QAdapterProp;
import com.eactive.eai.data.entity.onl.adapter.QAdapterPropGroup;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.querydsl.core.types.dsl.BooleanExpression;

@Service("adapterEMSService")
@Transactional
public class AdapterService extends AbstractDataService<Adapter, AdapterId, AdapterEMSRepository> {
	
	public Page<Adapter> selectList(Pageable pageable, OsidinstiSearch osidinstiSearch) {
		QAdapter qAdapter = QAdapter.adapter;
		QAdapterPropGroup qAdapterPropGroup = QAdapterPropGroup.adapterPropGroup;
		QAdapterGroup qAdapterGroup = QAdapterGroup.adapterGroup;
		QAdapterProp qAdapterProp = QAdapterProp.adapterProp;

		BooleanExpression predicate = buildPredicate(osidinstiSearch);

		List<Adapter> content = getJPAQueryFactory()
				.selectFrom(qAdapter)
				.join(qAdapter.adapterPropGroup, qAdapterPropGroup)
				.join(qAdapter.adapterPropGroup.adapterProps, qAdapterProp)
				.join(qAdapter.adapterGroup, qAdapterGroup)
				.where(predicate)
				.distinct()
				.offset(pageable.getOffset())
				.limit(pageable.getPageSize())
				.fetch();

		long total = getJPAQueryFactory()
				.select(qAdapter.countDistinct())
				.from(qAdapter)
				.where(predicate)
				.join(qAdapter.adapterPropGroup, qAdapterPropGroup)
				.join(qAdapter.adapterPropGroup.adapterProps, qAdapterProp)
				.join(qAdapter.adapterGroup, qAdapterGroup)
				.fetchOne();

		return new PageImpl<>(content, pageable, total);
	}
	
	public List<Adapter> findAllAdapter(OsidinstiSearch osidinstiSearch) {
		QAdapter qAdapter = QAdapter.adapter;
		
		BooleanExpression predicate = buildPredicate(osidinstiSearch);
		
		return getJPAQueryFactory().selectFrom(qAdapter)
												.where(predicate)
												.leftJoin(qAdapter.adapterPropGroup).fetchJoin()
												.leftJoin(qAdapter.adapterGroup).fetchJoin()
												.distinct()
												.fetch();
	}

	private BooleanExpression buildPredicate(OsidinstiSearch osidinstiSearch) {
		QAdapter qAdapter = QAdapter.adapter;
		QAdapterProp qAdapterProp = QAdapterProp.adapterProp;
		
		BooleanExpression predicate = qAdapterProp.adapterPropGroup.adapterProps.isNotEmpty()
				.and(qAdapterProp.id.prptyname.in("port.number", "URL", "host.name"));
		
		if (StringUtils.isNotBlank(osidinstiSearch.getSearchAdptrBzwkGroupName())) {
			predicate = predicate.and(qAdapter.id.adptrbzwkgroupname.containsIgnoreCase(osidinstiSearch.getSearchAdptrBzwkGroupName()));
		}
		
		if (StringUtils.isNotBlank(osidinstiSearch.getSearchIp())) {
			predicate = predicate.and(qAdapterProp.id.prptyname.in("host.name", "URL")
					.and(qAdapterProp.prpty2val.containsIgnoreCase(osidinstiSearch.getSearchIp())));
		}
		
		if (StringUtils.isNotBlank(osidinstiSearch.getSearchPortNum())) {
			predicate = predicate.and(qAdapterProp.id.prptyname.in("port.number", "URL")
					.and(qAdapterProp.prpty2val.containsIgnoreCase(osidinstiSearch.getSearchPortNum())));
		}
		
		if (StringUtils.isNotBlank(osidinstiSearch.getSearchInstiName())) {
			predicate = predicate.and(qAdapter.adapterGroup.adptrbzwkgroupdesc.containsIgnoreCase(osidinstiSearch.getSearchInstiName()));
		}
		
		return predicate;
	}

	public Adapter findAdapter(String adptrBzwkGroupName) {
		QAdapter qAdapter = QAdapter.adapter;
		
		return getJPAQueryFactory()
				.selectFrom(qAdapter)
				.distinct()
				.where(qAdapter.adapterGroup.adptrbzwkgroupname.eq(adptrBzwkGroupName))
				.fetchFirst();
	}

	public Iterable<Adapter> findByIdAdptrbzwkgroupname(String gstatsysadptrbzwkgroupname) {
		return repository.findAll(QAdapter.adapter.id.adptrbzwkgroupname.eq(gstatsysadptrbzwkgroupname));
	}
	

}
