/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.nlpcraft.model;

import java.io.*;
import java.util.*;

/**
 * An intent match context that can be passed into the callback of the matched intent.
 * Note that when using {@link NCIntent} and {@link NCIntentTerm}
 * annotations the callback method can be defined parameter-less (and this context won't be passed in).
 * If used, intent context must be the 1st formal parameter in intent callback.
 * <p>
 * Read full documentation in <a target=_ href="https://nlpcraft.apache.org/intent-matching.html">Intent Matching</a> section and review
 * <a target=_ href="https://github.com/apache/incubator-nlpcraft/tree/master/nlpcraft-examples">examples</a>.
 *
 * @see NCIntent
 * @see NCIntentTerm
 * @see NCIntentSkip
 * @see NCModelAddClasses
 * @see NCModelAddPackage
 * @see NCIntentSample
 * @see NCIntentSampleRef
 * @see NCIntentRef
 */
public interface NCIntentMatch extends NCMetadata, Serializable {
    /**
     * Gets ID of the matched intent.
     *
     * @return ID of the matched intent.
     */
    String getIntentId();

    /**
     * Gets context of the user input query.
     *
     * @return Original query context.
     */
    NCContext getContext();

    /**
     * Gets a subset of tokens representing matched intent. This subset is grouped by the matched terms
     * where a {@code null} sub-list defines an optional term. Order and index of sub-lists corresponds
     * to the order and index of terms in the matching intent. Number of sub-lists will always be the same
     * as the number of terms in the matched intent.
     * <p>
     * Note that unlike {@link #getVariant()} method
     * this method returns only subset of the tokens that were part of the matched intent. Specifically, it will
     * not return tokens for free words, stopwords or unmatched ("dangling") tokens.
     * <p>
     * Consider using {@link NCIntentTerm} annotation instead for simpler access to intent tokens.
     *
     * @return List of list of tokens representing matched intent.
     * @see #getVariant()
     * @see NCIntentTerm
     */
    List<List<NCToken>> getIntentTokens();

    /**
     * Gets tokens for given term. This is a companion method for {@link #getIntentTokens()}.
     * <p>
     * Consider using {@link NCIntentTerm} annotation instead for simpler access to intent tokens.
     *
     * @param idx Index of the term (starting from <code>0</code>).
     * @return List of tokens, potentially {@code null}, for given term.
     * @see NCIntentTerm
     * @see #getTermTokens(String) 
     */
    List<NCToken> getTermTokens(int idx);

    /**
     * Gets tokens for given term. This is a companion method for {@link #getIntentTokens()}.
     * <p>
     * Consider using {@link NCIntentTerm} annotation instead for simpler access to intent tokens.
     *
     * @param termId ID of the term for which to get tokens.
     * @return List of tokens, potentially {@code null}, for given term.
     * @see NCIntentTerm
     * @see #getTermTokens(int) 
     */
    List<NCToken> getTermTokens(String termId);

    /**
     * Gets sentence parsing variant that produced the matching for this intent. Returned variant is one of the
     * variants provided by {@link NCContext#getVariants()} methods. Note that tokens returned by this method are
     * a superset of the tokens returned by {@link #getIntentTokens()} method, i.e. not all tokens
     * from this variant may have been used in matching of the winning intent.
     * 
     * @return Sentence parsing variant that produced the matching for this intent.
     * @see #getIntentTokens() 
     */
    NCVariant getVariant();
}
