/*=============================================================================#
 # Copyright (c) 2010, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rhelp.core;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

import java.util.List;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.internal.rhelp.core.RHelpSearchIndexQueryIntern;
import org.eclipse.statet.internal.rhelp.core.index.REnvIndexSchema;
import org.eclipse.statet.internal.rhelp.core.index.REnvIndexSearchQuery;
import org.eclipse.statet.rj.renv.core.REnv;


@NonNullByDefault
public class RHelpSearchQuery extends RHelpSearchIndexQueryIntern {
	
	
	public static final int TOPIC_SEARCH= 1;
	public static final int FIELD_SEARCH= 2;
	public static final int DOC_SEARCH= 3;
	
	public static final String TOPICS_FIELD= REnvIndexSchema.ALIAS_TXT_FIELD_NAME;
	public static final String TITLE_FIELD= REnvIndexSchema.TITLE_TXT_FIELD_NAME;
	public static final String CONCEPTS_FIELD= REnvIndexSchema.CONCEPT_TXT_FIELD_NAME;
	
	
	private final int searchType;
	private final String searchText;
	private final ImList<String> fields;
	private final ImList<String> keywords;
	private final ImList<String> packages;
	
	private final @Nullable REnv rEnv;
	
	
	public RHelpSearchQuery(final int type, final String text, final List<String> fields,
			final List<String> keywords, final List<String> packages,
			final @Nullable REnv rEnv) {
		this.searchType= type;
		this.searchText= text;
		this.fields= ImCollections.toList(fields);
		this.keywords= ImCollections.toList(keywords);
		this.packages= ImCollections.toList(packages);
		this.rEnv= (rEnv != null) ? rEnv.resolve() : null;
	}
	
	
	public REnv getREnv() {
		return nonNullAssert(this.rEnv);
	}
	
	public int getSearchType() {
		return this.searchType;
	}
	
	public String getSearchString() {
		return this.searchText;
	}
	
	public ImList<String> getEnabledFields() {
		return this.fields;
	}
	
	public ImList<String> getKeywords() {
		return this.keywords;
	}
	
	public ImList<String> getPackages() {
		return this.packages;
	}
	
	public void validate() throws StatusException {
		if (this.rEnv == null) {
			throw new StatusException(new ErrorStatus(RHelpCore.BUNDLE_ID,
					"The R environment is missing." ));
		}
		if (this.rEnv.isDeleted()) {
			throw new StatusException(new ErrorStatus(RHelpCore.BUNDLE_ID,
					"The R environment no longer exists." ));
		}
		if (this.rEnv.get(REnvHelpConfiguration.class) == null) {
			throw new StatusException(new ErrorStatus(RHelpCore.BUNDLE_ID,
					"The R environment not supported." ));
		}
		
		if (!isIndexQueryOk()) {
			setIndexQuery(REnvIndexSearchQuery.compile(this));
		}
	}
	
	
	@Override
	public String toString() {
		return this.searchText;
	}
	
}
