package org.studiorailgun.ai.philosophy;

import java.util.List;
import java.util.stream.Collectors;

import org.studiorailgun.Globals;
import org.studiorailgun.ai.knowledge.Node;
import org.studiorailgun.ai.knowledge.Relation;
import org.studiorailgun.ai.knowledge.query.InstanceQuery;
import org.studiorailgun.ai.knowledge.query.filter.NameQueryFilter;
import org.studiorailgun.ai.knowledge.types.RelationTypes;

/**
 * Queries related to concepts or the idea of a concept
 */
public class ConceptQuery {
    
    /**
     * Gets the list of all concepts
     * @return The list of all concepts
     */
    public static List<Node> getAllConcepts(){
        Node conceptNode = Globals.web.getAnchors().getConceptNode();
        return InstanceQuery.getInstances(conceptNode);
    }

    /**
     * Gets a concept by its name
     * @param web The web
     * @param conceptName The name of the concept
     * @return The concept
     */
    public static Node getConcept(String conceptName){
        Node concept = Globals.web.getAnchors().getConceptNode();
        List<Node> concepts = InstanceQuery.getInstances(concept);
        return NameQueryFilter.withNodeName(concepts, conceptName);
    }

    /**
     * Gets the most specific concept that the child is an instance of
     * @param child The child
     * @return The most specific concept that the child is an instance of
     */
    public static Node getMostSpecificConcept(Node child){
        //get all concepts
        Node concept = Globals.web.getAnchors().getConceptNode();
        List<Node> concepts = InstanceQuery.getInstances(concept);

        //get the objects the child is an instance of
        List<Relation> relations = Globals.web.getRelationsOfChildNode(child);


        //filter to most specific concept
        List<Node> conceptParents = relations.stream()
            .filter(relation -> relation.getName().equals(RelationTypes.INSTANCE_OF))
            .filter(relation -> concepts.contains(relation.getParent()))
            .map(relation -> relation.getParent()).collect(Collectors.toList());

        if(conceptParents.size() < 1){
            throw new Error("Node somehow has no concept that it is an instance of! " + concept.getName());
        }

        //TODO: get most specific -- defaulting to first currently
        return conceptParents.get(0);
    }

}
