package org.studiorailgun.conversation.evaluators.transfer;

import org.studiorailgun.Globals;
import org.studiorailgun.conversation.evaluators.query.NounStack;
import org.studiorailgun.conversation.parser.NLPDependencies;
import org.studiorailgun.conversation.parser.PennTreebankTagSet;
import org.studiorailgun.conversation.tracking.Conversation;
import org.studiorailgun.conversation.tracking.Quote;
import org.studiorailgun.conversation.tracking.Sentence;
import org.studiorailgun.knowledge.KnowledgeWeb;
import org.studiorailgun.knowledge.query.NodePropQuery;

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

/**
 * 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();

        if(PennTreebankTagSet.isNoun(root.tag())){
            if(TransferEval.isCopularStatement(semanticGraph)){
                NounStack noun1 = NounStack.parse(semanticGraph, root);
                NounStack noun2 = null;
                for(IndexedWord child : semanticGraph.getChildList(root)){
                    if(PennTreebankTagSet.isNoun(child.tag())){
                        noun2 = NounStack.parse(semanticGraph, child);
                        break;
                    }
                }
                if(noun2 == null){
                    throw new Error("Failed to parse second noun! " + semanticGraph);
                }
                TransferEval.evaluateCopularStatement(conversation, quote, sentence, noun1, null);
            } 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, NounStack noun1, NounStack noun2){
        SemanticGraph graph = sentence.getGraph();
        IndexedWord verb = NLPDependencies.getCopular(graph);
        if(PennTreebankTagSet.isBe(verb.tag())){
            TransferEval.evaluateAssignmentStatement(conversation, quote, sentence, noun1, noun2);
        } 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, NounStack noun1, NounStack noun2){
        //if there is no node with this name already, create one
        System.out.println(sentence.getGraph());
        String noun1RootText = noun1.getIndexedWord().originalText();
        if(NodePropQuery.byName(noun1RootText).size() < 1){
            Globals.web.createNode(noun1RootText);
        }

    }

    /**
     * Checks if this is a copular statement
     * @param graph The graph
     * @return true if it is a copular statement, false otherwise
     */
    private static boolean isCopularStatement(SemanticGraph graph){
        IndexedWord root = graph.getFirstRoot();
        for(IndexedWord child : graph.getChildList(root)){
            GrammaticalRelation relation = graph.reln(root,child);
            if(NLPDependencies.isCopular(relation.getLongName())){
                return true;
            }
        }
        return false;
    }

}
