package org.studiorailgun.ai.conversation.evaluators.transfer;

import java.util.List;

import org.studiorailgun.Globals;
import org.studiorailgun.ai.conversation.evaluators.query.NounStack;
import org.studiorailgun.ai.conversation.synthesis.NounStackSynthesizer;
import org.studiorailgun.ai.conversation.synthesis.QualitySynthesizer;
import org.studiorailgun.ai.conversation.tracking.Conversation;
import org.studiorailgun.ai.conversation.tracking.Quote;
import org.studiorailgun.ai.conversation.tracking.Sentence;
import org.studiorailgun.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.query.InstanceQuery;
import org.studiorailgun.ai.knowledge.query.QualityQuery;
import org.studiorailgun.ai.knowledge.query.filter.InstanceQueryFilter;
import org.studiorailgun.ai.knowledge.query.filter.PossessionQueryFilter;
import org.studiorailgun.ai.philosophy.ConceptQuery;

/**
 * Interrogatives available
 */
public class Interrogative {

    /**
     * Evaluates a query of "which"
     * @param conversation The conversation
     * @param quote The quote
     * @param interrogative The interrogative noun
     * @param items The items noun
     * @return null
     */
    public static String evalWhichQuery(Conversation conversation, Quote quote, Sentence sentence, NounStack interrogative, NounStack items){

        //get the thing that has the quality
        if(QualityQuery.isQualityClarificationQuery(interrogative)){
            Node finalQualifier = ConceptQuery.getConcept(items.getIndexedWord().originalText());
            if(items.getPossessive() != null){
                List<Node> qualifierInstances = InstanceQuery.getInstances(finalQualifier);
                finalQualifier = PossessionQueryFilter.withPossessor(qualifierInstances, Globals.web.getAnchors().getSelfNode());
            }

            //get the actual qualities that we care about
            List<Node> qualitiesOfInstance = QualityQuery.getQualitiesOfInstance(finalQualifier);
            Node qualityType = QualityQuery.getRequestedQualityType(interrogative);
            List<Node> applicableQualities = InstanceQueryFilter.filter(qualitiesOfInstance, qualityType);

            //synthesize
            String subject = NounStackSynthesizer.synthesize(finalQualifier, items.getPossessive() != null);
            String verb = "is";
            String object = QualitySynthesizer.synthesize(applicableQualities, qualityType);

            return subject + " " + verb + " " + object;
        } else {
            throw new Error("Unknown query type!");
        }
    }

    /**
     * Evaluates a query of "what"
     * @param conversation The conversation
     * @param quote The quote
     * @param interrogative The interrogative noun
     * @param items The items noun
     * @return null
     */
    public static String evalWhatQuery(Conversation conversation, Quote quote, Sentence sentence, NounStack interrogative, NounStack items){
        if(QualityQuery.isQualityClarificationQuery(interrogative)){

            //get the thing that has the quality
            Node finalQualifier = ConceptQuery.getConcept(items.getIndexedWord().originalText());
            if(items.getPossessive() != null){
                List<Node> qualifierInstances = InstanceQuery.getInstances(finalQualifier);
                finalQualifier = PossessionQueryFilter.withPossessor(qualifierInstances, Globals.web.getAnchors().getSelfNode());
            }

            //get the actual qualities that we care about
            List<Node> qualitiesOfInstance = QualityQuery.getQualitiesOfInstance(finalQualifier);
            Node qualityType = QualityQuery.getRequestedQualityType(interrogative);
            List<Node> applicableQualities = InstanceQueryFilter.filter(qualitiesOfInstance, qualityType);

            //synthesize
            String subject = NounStackSynthesizer.synthesize(finalQualifier, items.getPossessive() != null);
            String verb = "is";
            String object = QualitySynthesizer.synthesize(applicableQualities, qualityType);

            return subject + " " + verb + " " + object;
        } else {
            throw new Error("Unknown query type!");
        }
    }

}
