package eu.dnetlib.oai;

import java.util.List;
import java.util.function.Function;

import eu.dnetlib.oai.info.RecordInfo;

/**
 * Interface for store used by the publisher. Different back-ends require different implementation.
 *
 * @param <T> class of the object that can be used to iterate results of a bulk request of records from the store.
 * @author alessia
 */
public interface PublisherStore<T extends Cursor> {

	/**
	 * Returns the identifier of this store.
	 *
	 * @return a String that identifies this store
	 */
	String getId();

	/**
	 * Gets the metadata format of this store.
	 *
	 * @return String
	 */
	String getMetadataFormat();

	/**
	 * Gets the interpretation of this store.
	 *
	 * @return String
	 */
	String getInterpretation();

	/**
	 * Gets the layout of this store.
	 *
	 * @return String
	 */
	String getLayout();

	/**
	 * Retrieves the record with the given identifier from this store.
	 *
	 * @param recordId identifier of the record to retrieve
	 * @return a RecordInfo instance representing the XML record
	 */
	RecordInfo getRecord(final String recordId);

	/**
	 * Retrieves the record with the given identifier from this store and apply the given unary function before delivering.
	 *
	 * @param recordId      identifier of the record to retrieve
	 * @param unaryFunction mapping from String to String
	 * @return a RecordInfo instance representing the XML record
	 */
	RecordInfo getRecord(final String recordId, final Function<String, String> unaryFunction);

	/**
	 * Retrieves the records matching the given query string.
	 *
	 * @param queryString  search criterion
	 * @param bodyIncluded false to get only identifiers, true to also get the body of records
	 * @param limit        max number of records to return. 0 means no limit.
	 * @return an instance of T that can be used to iterate over the results.
	 */
	T getRecords(final String queryString, final boolean bodyIncluded, final int limit);

	/**
	 * Retrieves the records matching the given query string and apply the given unary function before delivering.
	 *
	 * @param queryString   search criterion
	 * @param unaryFunction mapping from String to String
	 * @param bodyIncluded  false to get only identifiers, true to also get the body of records
	 * @param limit         max number of records to return. 0 means no limit.
	 * @return an instance of T that can be used to iterate over the results.
	 */
	T getRecords(final String queryString, final Function<String, String> unaryFunction, final boolean bodyIncluded, final int limit);

	/**
	 * Gets informaton about the indices available on this store.
	 *
	 * @return a List with information about the indices of this store.
	 */
	List<PublisherField> getIndices();

	/**
	 * Ensures the indices on this store.
	 */
	void ensureIndices();

	/**
	 * Feeds the store with the given records.
	 *
	 * @param records XML records to store.
	 * @param source  String that identifies the record source.
	 * @return the number of stored records.
	 */
	int feed(final Iterable<String> records, final String source);

	/**
	 * Drops the content of the store.
	 */
	void drop();

	/**
	 * Drops the elements matching the query from the store.
	 *
	 * @param queryString
	 */
	void drop(final String queryString);

	/**
	 * Counts the number of records in this store.
	 *
	 * @return the size of the store.
	 */
	int count();

	/**
	 * Counts the number of records in this store matching the query.
	 *
	 * @param queryString query
	 * @return the size of the store.
	 */
	int count(final String queryString);

}
