/*
 * Copyright 2020 B2i Healthcare Pte Ltd, http://b2i.sg
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.b2international.snowowl.core.request;

import com.b2international.snowowl.core.domain.BranchContext;
import com.b2international.snowowl.core.domain.Concepts;
import com.b2international.snowowl.core.events.AsyncRequest;
import com.b2international.snowowl.core.request.ConceptSearchRequestEvaluator.OptionKey;

/**
 * @since 7.5
 */
public final class ConceptSearchRequestBuilder extends SearchResourceRequestBuilder<ConceptSearchRequestBuilder, BranchContext, Concepts>
		implements RevisionIndexRequestBuilder<Concepts>, TermFilterSupport<ConceptSearchRequestBuilder> {

	/**
	 * Filters matches by their active/inactive status. 
	 * 
	 * @param active
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByActive(Boolean active) {
		return addOption(OptionKey.ACTIVE, active);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public ConceptSearchRequestBuilder filterByTerm(TermFilter termFilter) {
		return addOption(OptionKey.TERM, termFilter);
	}

	/**
	 * Filters matches by a query expression defined in the target code system's query language.
	 * 
	 * @param query
	 *            - the query expression
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByQuery(String query) {
		return addOption(OptionKey.QUERY, query);
	}

	/**
	 * Filter by multiple query expressions defined in the target code system's query language.
	 * 
	 * @param inclusions
	 *            - query expressions that include matches
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByInclusions(Iterable<String> inclusions) {
		return addOption(OptionKey.QUERY, inclusions);
	}

	/**
	 * Exclude matches by specifying one exclusion query defined in the target code system's query language.
	 * 
	 * @param exclusion
	 *            - query expression that exclude matches
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByExclusion(String exclusion) {
		return addOption(OptionKey.MUST_NOT_QUERY, exclusion);
	}
	
	/**
	 * Exclude matches by specifying one or more exclusion queries defined in the target code system's query language.
	 * 
	 * @param exclusions
	 *            - query expression that exclude matches
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByExclusions(Iterable<String> exclusions) {
		return addOption(OptionKey.MUST_NOT_QUERY, exclusions);
	}
	
	/**
	 * Filters terms by their type.
	 * 
	 * @param termType
	 *            - String representation of the term type filtering
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByTermType(String termType) {
		return addOption(OptionKey.TERM_TYPE, termType);
	}

	/**
	 * Filters concepts by their type.
	 * 
	 * @param type
	 *            - String representation of the concept type filtering
	 * @return
	 */
	public ConceptSearchRequestBuilder filterByType(String type) {
		return addOption(OptionKey.TYPE, type);
	}
	
	/**
	 * Sets the preferred display term to return for every code system
	 * 
	 * @param preferredDisplay
	 *            - String representation of the preferred display
	 * @return
	 */
	public ConceptSearchRequestBuilder setPreferredDisplay(String preferredDisplay) {
		return addOption(OptionKey.DISPLAY, preferredDisplay);
	}

	@Override
	protected SearchResourceRequest<BranchContext, Concepts> createSearch() {
		return new ConceptSearchRequest();
	}

	/**
	 * @deprecated - use the {@link #build(String)} method instead
	 */
	@Override
	public AsyncRequest<Concepts> build(String repositoryId, String branch) {
		throw new UnsupportedOperationException("This build() method is unsupported for generic requests");
	}

}

@@ -667,16 +667,133 @@
 quest;%0A%0A
+import com.b2international.commons.exceptions.BadRequestException;%0Aimport com.b2international.snowowl.core.CodeType;%0A
 import c
@@ -1052,16 +1052,63 @@
 tionKey;
+%0Aimport com.google.common.collect.ImmutableSet;
 %0A%0A/**%0A *
@@ -3569,24 +3569,403 @@
 ing type) %7B%0A
+%09%09try %7B%0A%09%09%09return filterByTypes(ImmutableSet.of(CodeType.valueOf(type)));%0A%09%09%7D catch (Exception e) %7B%0A%09%09%09throw new BadRequestException(%22%25s is not a valid CodeType enum.%22, type);%0A%09%09%7D%0A%09%7D%0A%0A%09public ConceptSearchRequestBuilder filterByType(CodeType type) %7B%0A%09%09return filterByTypes(ImmutableSet.of(type));%0A%09%7D%0A%0A%09public ConceptSearchRequestBuilder filterByTypes(Iterable%3CCodeType%3E types) %7B%0A
 %09%09return add
@@ -3991,24 +3991,25 @@
 PE, type
+s
 );%0A%09%7D%0A%09%0A
 %09/**%0A%09 *
@@ -3992,32 +3992,34 @@
 E, types);%0A%09%7D%0A%09%0A
+%09%0A
 %09/**%0A%09 * Sets th

support filtering by multi value