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

import org.studiorailgun.ai.conversation.parser.NLPDependencies;
import org.studiorailgun.ai.conversation.parser.PennTreebankTagSet;
import org.studiorailgun.ai.conversation.parser.depend.Argument;
import org.studiorailgun.ai.conversation.parser.depend.Clause;
import org.studiorailgun.ai.conversation.parser.depend.Predicate;
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.conversation.web.ArgumentQuery;
import org.studiorailgun.ai.conversation.web.MetaQuery;
import org.studiorailgun.ai.knowledge.Node;

import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.semgraph.SemanticGraph;

/**
 * Evaluates a transfer statement
 */
public class TransferEval {
    
    /**
     * Evaluates a quote
     * @param conversation The conversation
     * @param quote The quote
     */
    public static void evaluate(Conversation conversation, Quote quote, Sentence sentence){
        SemanticGraph semanticGraph = sentence.getGraph();
        if(semanticGraph.getRoots().size() > 1){
            String message = "Multiple roots to sentence!\n" +
            "\"" + quote.getRaw() + "\"\n" +
            semanticGraph;
            throw new UnsupportedOperationException(message);
        }
        IndexedWord root = semanticGraph.getFirstRoot();
        Clause mainClause = sentence.getMainClause();
        Predicate pred = mainClause.getPredicate();

        if(PennTreebankTagSet.isNoun(root.tag())){
            if(TransferEval.isCopularStatement(pred)){
                //this is a copular predicate
                Argument argument1 = mainClause.getSubject();
                Argument argument2 = mainClause.getPredicate().getCopularArg();
                if(argument1 == null || argument2 == null){
                    String message = "Failed to parse arguments for copular statement! \n" +
                    argument1 + " " + argument2 + "\n" +
                    sentence.getRaw() + "\n" +
                    semanticGraph;
                    throw new Error(message);
                }
                TransferEval.evaluateCopularStatement(conversation, quote, sentence, argument1, argument2);
            } else {
                String message = "Unsupported root type!\n" +
                    "\"" + sentence.getRaw() + "\"\n" +
                    semanticGraph;
                throw new UnsupportedOperationException(message);
            }
        } else {
            String message = "Unsupported root type!\n" +
                "\"" + sentence.getRaw() + "\"\n" +
                semanticGraph;
            throw new UnsupportedOperationException(message);
        }
    }

    /**
     * Evaluates a copular statement
     * @param conversation The conversation
     * @param quote The quote
     * @param sentence The sentence containing the copular statement
     * @param noun1 The first noun stack
     * @param noun2 The second noun stack
     */
    private static void evaluateCopularStatement(Conversation conversation, Quote quote, Sentence sentence, Argument subject, Argument object){
        SemanticGraph graph = sentence.getGraph();
        IndexedWord verb = NLPDependencies.getCopular(graph);
        if(PennTreebankTagSet.isBe(verb.tag())){
            TransferEval.evaluateAssignmentStatement(conversation, quote, sentence, subject, object);
        } else {
            throw new Error("Unsupported verb type! " + graph);
        }
    }

    /**
     * Evaluates a statement that is equating two nouns
     * @param conversation The conversation
     * @param quote The quote
     * @param sentence The sentence
     */
    private static void evaluateAssignmentStatement(Conversation conversation, Quote quote, Sentence sentence, Argument subjectArg, Argument objectArg){
        //if there is no node with this name already, create one
        System.out.println(sentence.getGraph());

        Node subjectNode = ArgumentQuery.getArgument(quote, subjectArg);
        if(subjectNode == null){
            throw new Error("Error querying subject!");
        }

        Node objectNode = ArgumentQuery.getArgument(quote, objectArg);
        if(objectNode == null){
            throw new Error("Error querying object!");
        }
        //make an equivalence link here if it doesn't exist already
        if(MetaQuery.isLearnable(subjectNode)){

        } else if(MetaQuery.isLearnable(objectNode)){

        } else {
            String message = "Information already stored?\n" +
            sentence.getGraph();
            throw new Error(message);
        }

        //for the moment, assume the other noun is a concept
        
    }

    /**
     * Checks if this is a copular statement
     * @param pred The predicate of the sentence
     * @return true if it is a copular statement, false otherwise
     */
    private static boolean isCopularStatement(Predicate pred){
        return pred.getCopular() != null;
    }

}
