package org.apache.rya.indexing;

import java.util.Map;
import java.util.Set;

import org.apache.hadoop.conf.Configuration;
import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
import org.joda.time.DateTime;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.algebra.QueryModelVisitor;

import com.google.common.base.Joiner;
import com.google.common.collect.Maps;

/*
 * 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 info.aduna.iteration.CloseableIteration;

//Indexing Node for temporal expressions to be inserted into execution plan
//to delegate temporal portion of query to temporal index
public class TemporalTupleSet extends ExternalTupleSet {

    private final Configuration conf;
    private final TemporalIndexer temporalIndexer;
    private final IndexingExpr filterInfo;

    public TemporalTupleSet(final IndexingExpr filterInfo, final TemporalIndexer temporalIndexer) {
        this.filterInfo = filterInfo;
        this.temporalIndexer = temporalIndexer;
        conf = temporalIndexer.getConf();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Set<String> getBindingNames() {
        return filterInfo.getBindingNames();
    }

    /**
     * {@inheritDoc}
     * <p>
     * Note that we need a deep copy for everything that (during optimizations)
     * can be altered via {@link #visitChildren(QueryModelVisitor)}
     */
    @Override
    public TemporalTupleSet clone() {
        return new TemporalTupleSet(filterInfo, temporalIndexer);
    }

    @Override
    public double cardinality() {
        return 0.0; // No idea how the estimate cardinality here.
    }

    @Override
    public String getSignature() {

        return "(TemporalTuple Projection) " + "variables: " + Joiner.on(", ").join(getBindingNames()).replaceAll("\\s+", " ");
    }

    @Override
    public boolean equals(final Object other) {
        if (other == this) {
            return true;
        }
        if (!(other instanceof TemporalTupleSet)) {
            return false;
        }
        final TemporalTupleSet arg = (TemporalTupleSet) other;
        return filterInfo.equals(arg.filterInfo);
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31*result + filterInfo.hashCode();

        return result;
    }

    /**
     * Returns an iterator over the result set associated with contained IndexingExpr.
     * <p>
     * Should be thread-safe (concurrent invocation {@link OfflineIterable} this
     * method can be expected with some query evaluators.
     */
    @Override
    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final BindingSet bindings)
            throws QueryEvaluationException {
        final URI funcURI = filterInfo.getFunction();
        final SearchFunction searchFunction = new TemporalSearchFunctionFactory(conf, temporalIndexer).getSearchFunction(funcURI);

        if(filterInfo.getArguments().length > 1) {
            throw new IllegalArgumentException("Index functions do not support more than two arguments.");
        }

        final String queryText = ((Value) filterInfo.getArguments()[0]).stringValue();
        return IteratorFactory.getIterator(filterInfo.getSpConstraint(), bindings, queryText, searchFunction);
    }

    //returns appropriate search function for a given URI
    //search functions used by TemporalIndexer to query Temporal Index
    public static class TemporalSearchFunctionFactory  {
        private final Map<URI, SearchFunction> SEARCH_FUNCTION_MAP = Maps.newHashMap();
        private final TemporalIndexer temporalIndexer;

        public TemporalSearchFunctionFactory(final Configuration conf, final TemporalIndexer temporalIndexer) {
            this.temporalIndexer = temporalIndexer;
        }

        /**
         * Get a {@link TemporalSearchFunction} for a give URI.
         *
         * @param searchFunction
         * @return
         */
        public SearchFunction getSearchFunction(final URI searchFunction) {
            SearchFunction geoFunc = null;
            try {
                geoFunc = getSearchFunctionInternal(searchFunction);
            } catch (final QueryEvaluationException e) {
                e.printStackTrace();
            }

            return geoFunc;
        }

        private SearchFunction getSearchFunctionInternal(final URI searchFunction) throws QueryEvaluationException {
            final SearchFunction sf = SEARCH_FUNCTION_MAP.get(searchFunction);

            if (sf != null) {
                return sf;
            } else {
                throw new QueryEvaluationException("Unknown Search Function: " + searchFunction.stringValue());
            }
        }

        private final SearchFunction TEMPORAL_InstantAfterInstant = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInstant queryInstant = new TemporalInstantRfc3339(DateTime.parse(searchTerms));
                return temporalIndexer.queryInstantAfterInstant(queryInstant, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantAfterInstant";
            };
        };
        private final SearchFunction TEMPORAL_InstantBeforeInstant = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInstant queryInstant = new TemporalInstantRfc3339(DateTime.parse(searchTerms));
                return temporalIndexer.queryInstantBeforeInstant(queryInstant, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantBeforeInstant";
            };
        };

        private final SearchFunction TEMPORAL_InstantEqualsInstant = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInstant queryInstant = new TemporalInstantRfc3339(DateTime.parse(searchTerms));
                return temporalIndexer.queryInstantEqualsInstant(queryInstant, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantEqualsInstant";
            };
        };

        private final SearchFunction TEMPORAL_InstantAfterInterval = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInterval queryInterval = TemporalInstantRfc3339.parseInterval(searchTerms);
                return temporalIndexer.queryInstantAfterInterval(queryInterval, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantAfterInterval";
            };
        };

        private final SearchFunction TEMPORAL_InstantBeforeInterval = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInterval queryInterval = TemporalInstantRfc3339.parseInterval(searchTerms);
                return temporalIndexer.queryInstantBeforeInterval(queryInterval, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantBeforeInterval";
            };
        };

        private final SearchFunction TEMPORAL_InstantInsideInterval = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInterval queryInterval = TemporalInstantRfc3339.parseInterval(searchTerms);
                return temporalIndexer.queryInstantInsideInterval(queryInterval, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantInsideInterval";
            };
        };

        private final SearchFunction TEMPORAL_InstantHasBeginningInterval = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInterval queryInterval = TemporalInstantRfc3339.parseInterval(searchTerms);
                return temporalIndexer.queryInstantHasBeginningInterval(queryInterval, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantHasBeginningInterval";
            };
        };

        private final SearchFunction TEMPORAL_InstantHasEndInterval = new SearchFunction() {
            @Override
            public CloseableIteration<Statement, QueryEvaluationException> performSearch(final String searchTerms,
                    final StatementConstraints contraints) throws QueryEvaluationException {
                final TemporalInterval queryInterval = TemporalInstantRfc3339.parseInterval(searchTerms);
                return temporalIndexer.queryInstantHasEndInterval(queryInterval, contraints);
            }

            @Override
            public String toString() {
                return "TEMPORAL_InstantHasEndInterval";
            };
        };

        {
            final String TEMPORAL_NS = "tag:rya-rdf.org,2015:temporal#";

            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"after"), TEMPORAL_InstantAfterInstant);
            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"before"), TEMPORAL_InstantBeforeInstant);
            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"equals"), TEMPORAL_InstantEqualsInstant);

            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"beforeInterval"), TEMPORAL_InstantBeforeInterval);
            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"afterInterval"), TEMPORAL_InstantAfterInterval);
            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"insideInterval"), TEMPORAL_InstantInsideInterval);
            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"hasBeginningInterval"),
                    TEMPORAL_InstantHasBeginningInterval);
            SEARCH_FUNCTION_MAP.put(new URIImpl(TEMPORAL_NS+"hasEndInterval"), TEMPORAL_InstantHasEndInterval);
        }
    }
}