package org.apache.rya.indexing.statement.metadata.matching;
/*
 * 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.
 */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
import org.apache.rya.api.domain.RyaURI;
import org.apache.rya.api.resolver.RdfToRyaConversions;
import org.apache.rya.indexing.external.matching.ExternalSetProvider;
import org.apache.rya.indexing.external.matching.QuerySegment;
import org.openrdf.model.URI;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.algebra.QueryModelNode;
import org.openrdf.query.algebra.StatementPattern;
import org.openrdf.query.algebra.Var;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

/**
 * This class extracts all valid {@Link StatementMetadataNode}s from the provided {@link QuerySegment}s.
 *
 */
public class StatementMetadataExternalSetProvider implements ExternalSetProvider<StatementMetadataNode<?>> {

    private List<RyaURI> expectedURI = Arrays.asList(RdfToRyaConversions.convertURI(OWLReify.SOURCE),
            RdfToRyaConversions.convertURI(OWLReify.PROPERTY), RdfToRyaConversions.convertURI(OWLReify.TARGET),
            RdfToRyaConversions.convertURI(RDF.TYPE));
    private Multimap<Var, StatementPattern> reifiedQueries;
    private Set<RyaURI> metadataProperties;
    private RdfCloudTripleStoreConfiguration conf;

    public StatementMetadataExternalSetProvider(RdfCloudTripleStoreConfiguration conf) {
        this.metadataProperties = conf.getStatementMetadataProperties();
        this.conf = conf;
    }

    /**
     * This method extracts all {@link StatementMetadataNode}s from the provided {@link QuerySegment}.
     * It looks through the provided QuerySegment for all combinations of {@link StatementPattern}s that 
     * represent a reified query and combines those into a StatementPatternNode.  A StatementPattern cannot
     * be used in more than one reified query and StatementPatternNode.
     */
    @Override
    public List<StatementMetadataNode<?>> getExternalSets(QuerySegment<StatementMetadataNode<?>> segment) {

        reifiedQueries = HashMultimap.create();

        List<StatementMetadataNode<?>> metadataList = new ArrayList<>();
        for (QueryModelNode node : segment.getUnOrderedNodes()) {
            if (node instanceof StatementPattern) {
                StatementPattern sp = (StatementPattern) node;
                reifiedQueries.put(sp.getSubjectVar(), sp);
            }
        }

        for (Var var : reifiedQueries.keySet()) {
            Collection<StatementPattern> patterns = removeInvalidProperties(reifiedQueries.get(var));
            if (StatementMetadataNode.verifyHasCorrectTypePattern(patterns)) {
                metadataList.add(new StatementMetadataNode<>(patterns, conf));
            }
        }

        return metadataList;
    }

    @Override
    public Iterator<List<StatementMetadataNode<?>>> getExternalSetCombos(
            QuerySegment<StatementMetadataNode<?>> segment) {
        Set<List<StatementMetadataNode<?>>> combos = new HashSet<>();
        combos.add(getExternalSets(segment));
        return combos.iterator();
    }

    private Set<StatementPattern> removeInvalidProperties(Collection<StatementPattern> patterns) {

        Set<StatementPattern> finalPatterns = new HashSet<>();
        
        for (StatementPattern pattern : patterns) {
            Var var = pattern.getPredicateVar();
            if (var.getValue() != null && var.getValue() instanceof URI) {
                RyaURI uri = RdfToRyaConversions.convertURI((URI) var.getValue());
                if(expectedURI.contains(uri) || metadataProperties.contains(uri)) {
                    finalPatterns.add(pattern);
                }
            }
        }
        return finalPatterns;
    }

}
