/*
 * Copyright 2011-2015 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.snomed.datastore;

import java.io.IOException;
import java.text.MessageFormat;

import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.search.Query;

import com.b2international.snowowl.snomed.SnomedConstants.Concepts;
import com.b2international.snowowl.snomed.datastore.index.mapping.SnomedMappings;
import com.b2international.snowowl.snomed.datastore.index.mapping.SnomedQueryBuilder;

/**
 * Enumerates the possible collection modes an array of {@link IsAStatement}s can be returned in.
 *
 */
public enum StatementCollectionMode {

	NO_IDS {
		@Override public NumericDocValues getNumericDocValues(final AtomicReader leafReader) throws IOException {
			return null;
		}

		@Override public boolean isLeafCollectible(final NumericDocValues idsValues) {
			return true;
		}

		@Override public long getIdValue(final NumericDocValues idsValues, final int docId) {
			return -1L;
		}

		@Override public IsAStatement createStatement(final long sourceId, final long destinationId, final long idOrKey) {
			return new SnomedIsAStatement(sourceId, destinationId);
		}

		@Override public IsAStatement[] createArray(final int expectedSize) {
			return new SnomedIsAStatement[expectedSize];
		}
	},

	WITH_RELATIONSHIP_IDS {
		@Override public NumericDocValues getNumericDocValues(final AtomicReader leafReader) throws IOException {
			return SnomedMappings.id().getDocValues(leafReader);
		}

		@Override public IsAStatementWithId createStatement(final long sourceId, final long destinationId, final long idOrKey) {
			return new SnomedIsAStatementWithId(sourceId, destinationId, idOrKey);
		}

		@Override public IsAStatement[] createArray(final int expectedSize) {
			return new SnomedIsAStatementWithId[expectedSize];
		}
	},

	ALL_TYPES_NO_IDS {
		
		@Override
		public String getType() {
			return null;
		}
		
		@Override public String getIdValuesField() {
			return SnomedMappings.relationshipType().fieldName();
		}

		@Override public IsAStatement createStatement(final long sourceId, final long destinationId, final long idOrKey) {
			return new SnomedStatement(sourceId, idOrKey, destinationId);
		}

		@Override public IsAStatement[] createArray(final int expectedSize) {
			return new SnomedStatement[expectedSize];
		}
		
	},
	
	STATED_ISA_ONLY {

		@Override
		public String getCharacteristicType() {
			return Concepts.STATED_RELATIONSHIP;
		}
		
		@Override public NumericDocValues getNumericDocValues(final AtomicReader leafReader) throws IOException {
			return SnomedMappings.id().getDocValues(leafReader);
		}
		
		@Override
		public IsAStatement createStatement(long sourceId, long destinationId, long idOrKey) {
			return new SnomedIsAStatementWithId(sourceId, destinationId, idOrKey);
		}
		
		@Override public IsAStatement[] createArray(final int expectedSize) {
			return new SnomedIsAStatementWithId[expectedSize];
		}

	},
	
	INFERRED_ISA_ONLY {

		@Override
		public String getCharacteristicType() {
			return Concepts.INFERRED_RELATIONSHIP;
		}
		
		@Override public NumericDocValues getNumericDocValues(final AtomicReader leafReader) throws IOException {
			return SnomedMappings.id().getDocValues(leafReader);
		}
		
		@Override
		public IsAStatement createStatement(long sourceId, long destinationId, long idOrKey) {
			return new SnomedIsAStatementWithId(sourceId, destinationId, idOrKey);
		}
		
		@Override public IsAStatement[] createArray(final int expectedSize) {
			return new SnomedIsAStatementWithId[expectedSize];
		}

	};

	/**
	 * @param idsValues the docvalues source to check
	 * 
	 * @return {@code true} if the docvalues source is not {@code null}, {@code false} otherwise
	 */
	public boolean isLeafCollectible(final NumericDocValues idsValues) {
		return idsValues != null;
	}

	public String getIdValuesField() {
		throw new IllegalStateException(MessageFormat.format("No ID field specified for collection mode {0}.", name()));
	}

	public NumericDocValues getNumericDocValues(final AtomicReader leafReader) throws IOException {
		return leafReader.getNumericDocValues(getIdValuesField());
	}

	public long getIdValue(final NumericDocValues idsValues, final int docId) {
		return idsValues.get(docId);
	}
	
	/*<p>By default returns with a query that accepts active relationships with IS_A type.*/
	public String getType() {
		return Concepts.IS_A;
	}
	
	public String getCharacteristicType() {
		return null;
	}

	/**
	 * Returns with the index query to collect all relevant relationships.
	 */
	public final Query getQuery() {
		final SnomedQueryBuilder query = SnomedMappings.newQuery().active().relationship();
		if (getType() != null) {
			query.relationshipType(getType());
		}
		if (getCharacteristicType() != null) {
			query.relationshipCharacteristicType(getCharacteristicType());
		}
		return query.matchAll();
	}

	/**
	 * @param sourceId
	 * @param destinationId
	 * @param idOrKey
	 * @return
	 */
	public abstract IsAStatement createStatement(long sourceId, long destinationId, long idOrKey);

	public abstract IsAStatement[] createArray(int expectedSize);
	
}
@@ -1919,539 +1919,8 @@
 %7D,%0A%0A
-%09WITH_RELATIONSHIP_IDS %7B%0A%09%09@Override public NumericDocValues getNumericDocValues(final AtomicReader leafReader) throws IOException %7B%0A%09%09%09return SnomedMappings.id().getDocValues(leafReader);%0A%09%09%7D%0A%0A%09%09@Override public IsAStatementWithId createStatement(final long sourceId, final long destinationId, final long idOrKey) %7B%0A%09%09%09return new SnomedIsAStatementWithId(sourceId, destinationId, idOrKey);%0A%09%09%7D%0A%0A%09%09@Override public IsAStatement%5B%5D createArray(final int expectedSize) %7B%0A%09%09%09return new SnomedIsAStatementWithId%5BexpectedSize%5D;%0A%09%09%7D%0A%09%7D,%0A%0A
 %09ALL

Remove unused statement collection mode