using Lucene.Net.Index;
using Lucene.Net.Queries;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Util;
using System;
using System.IO;

namespace Lucene.Net.Spatial
{
    /*
     * 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.
     */

    /// <summary>
    /// A Spatial Filter implementing <see cref="SpatialOperation.IsDisjointTo"/> in terms
    /// of a <see cref="SpatialStrategy">SpatialStrategy</see>'s support for
    /// <see cref="SpatialOperation.Intersects"/>.
    /// A document is considered disjoint if it has spatial data that does not
    /// intersect with the query shape.  Another way of looking at this is that it's
    /// a way to invert a query shape.
    /// 
    /// @lucene.experimental
    /// </summary>
    public class DisjointSpatialFilter : Filter
    {
        private readonly string field;//maybe null
        private readonly Filter intersectsFilter;

        /// <param name="strategy">Needed to compute intersects</param>
        /// <param name="args">Used in spatial intersection</param>
        /// <param name="field">
        /// This field is used to determine which docs have spatial data via
        /// <see cref="IFieldCache.GetDocsWithField(AtomicReader, string)"/>.
        /// Passing null will assume all docs have spatial data.
        /// </param>
        public DisjointSpatialFilter(SpatialStrategy strategy, SpatialArgs args, string field)
        {
            this.field = field;

            // TODO consider making SpatialArgs cloneable
            SpatialOperation origOp = args.Operation; //copy so we can restore
            args.Operation = SpatialOperation.Intersects; //temporarily set to intersects
            intersectsFilter = strategy.MakeFilter(args);
            args.Operation = origOp;
        }

        //restore so it looks like it was
        public override bool Equals(object o)
        {
            if (this == o)
            {
                return true;
            }
            if (o == null || GetType() != o.GetType())
            {
                return false;
            }
            var that = (DisjointSpatialFilter)o;
            if (field != null ? !field.Equals(that.field, StringComparison.Ordinal) : that.field != null)
            {
                return false;
            }
            if (!intersectsFilter.Equals(that.intersectsFilter))
            {
                return false;
            }
            return true;
        }

        public override int GetHashCode()
        {
            int result = field != null ? field.GetHashCode() : 0;
            result = 31 * result + intersectsFilter.GetHashCode();
            return result;
        }

        /// <exception cref="IOException"></exception>
        public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
        {
            IBits docsWithField;
            if (field == null)
            {
                docsWithField = null;
            }
            else
            {
                //NOTE By using the FieldCache we re-use a cache
                // which is nice but loading it in this way might be slower than say using an
                // intersects filter against the world bounds. So do we add a method to the
                // strategy, perhaps?  But the strategy can't cache it.
                docsWithField = FieldCache.DEFAULT.GetDocsWithField((context.AtomicReader), field);

                int maxDoc = context.AtomicReader.MaxDoc;
                if (docsWithField.Length != maxDoc)
                {
                    throw new InvalidOperationException("Bits length should be maxDoc (" + maxDoc + ") but wasn't: " + docsWithField);
                }

                if (docsWithField is Bits.MatchNoBits)
                {
                    return null;//match nothing
                }
                else if (docsWithField is Bits.MatchAllBits)
                {
                    docsWithField = null;//all docs
                }
            }
            
            //not so much a chain but a way to conveniently invert the Filter
            DocIdSet docIdSet = new ChainedFilter(new Filter[] { intersectsFilter }, ChainedFilter.ANDNOT).GetDocIdSet(context, acceptDocs);
            return BitsFilteredDocIdSet.Wrap(docIdSet, docsWithField);
        }
    }
}