/*
 * 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.rya.rdftriplestore.inference;

import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.query.algebra.Extension;
import org.eclipse.rdf4j.query.algebra.ExtensionElem;
import org.eclipse.rdf4j.query.algebra.StatementPattern;
import org.eclipse.rdf4j.query.algebra.Var;

/**
 * Expands the query tree to account for any relevant has-self class expressions
 * in the ontology known to the {@link InferenceEngine}.
 *
 * Only operates on {@link StatementPattern} nodes, and only those including a
 * defined type or defined predicate which is relevant to a has-self expression
 * in the ontology. When applicable, replaces the node with one or more
 * {@link InferUnion}s, one of whose leaves is the original StatementPattern.
 *
 * A has-self restriction defines the set of resources that are connected to
 * themselves by a property. If the ontology states that a type is a resource
 * that has a self referencing property, then the inference engine should:
 * <li>1. Rewrite queries of the from ?x rdf:type :T to find all resources
 * matching ?x :P ?x (as well as anything explicitly stated to be of type :T)
 * </li>
 * <li>2. Rewrite queries of the from :CONST :P ?o or ?subj :P :CONST to match
 * :CONST if :CONST is known to have the type :T
 * </li>
 */
public class HasSelfVisitor extends AbstractInferVisitor {
    private static final Var TYPE_VAR = new Var(RDF.TYPE.stringValue(), RDF.TYPE);

    /**
     * Creates a new {@link HasSelfVisitor}.
     * @param conf The {@link RdfCloudTripleStoreConfiguration}.
     * @param inferenceEngine The InferenceEngine containing the relevant ontology.
     */
    public HasSelfVisitor(final RdfCloudTripleStoreConfiguration conf, final InferenceEngine inferenceEngine) {
        super(conf, inferenceEngine);
        include = conf.isInferHasSelf();
    }

    @Override
    protected void meetSP(final StatementPattern node) throws Exception {
        final IRI pred = (IRI) node.getPredicateVar().getValue();
        final Var obj = node.getObjectVar();
        //if originalSP like (?s rdf:type :C1):  require that C1 is defined, i.e. not a variable
        // node <- originalSP
        final StatementPattern clone = node.clone();
        if (RDF.TYPE.equals(pred) && obj.isConstant()) {
            //for property in getHasSelfImplyingType(C1):
            if (obj.getValue() instanceof IRI) {
                for (final IRI property : inferenceEngine.getHasSelfImplyingType((IRI) obj.getValue())) {
                    //node <- InferUnion(node, StatementPattern(?s, property, ?s)).
                    final InferUnion union = new InferUnion(clone,
                            new StatementPattern(clone.getSubjectVar(),
                                                 new Var(property.stringValue(), property),
                                                 clone.getSubjectVar()));
                    //originalSP.replaceWith(node)
                    node.replaceWith(union);
                }
            }
        //else if originalSP like (s :p o):  where p is not a variable and at least one of s and o are variables
        } else if (node.getPredicateVar().isConstant()
               && (!node.getSubjectVar().isConstant() ||
                   !node.getObjectVar().isConstant())) {
            //for type in getHasSelfImplyingProperty(p):
            for (final Resource type : inferenceEngine.getHasSelfImplyingProperty(pred)) {
                final Extension extension;
                if(obj.isConstant()) { // subject is the variable
                    //Extension(StatementPattern(o, rdf:type, type), ExtensionElem(o, "s"))
                    extension = new Extension(
                            new StatementPattern(obj, TYPE_VAR, new Var(type.stringValue(), type)),
                            new ExtensionElem(obj, node.getSubjectVar().getName()));
                } else { //o is a variable and s may either be defined or a variable
                    //Extension(StatementPattern(s, rdf:type, type), ExtensionElem(s, "o"))
                    extension = new Extension(
                            new StatementPattern(node.getSubjectVar(), TYPE_VAR, new Var(type.stringValue(), type)),
                            new ExtensionElem(node.getSubjectVar(), obj.getName()));
                }
                // node <- InferUnion(node, newNode)
                final InferUnion union = new InferUnion(extension, clone);
                node.replaceWith(union);
            }
        }
    }
}