﻿using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Queries.Function;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Util;
using Spatial4n.Core.Context;
using Spatial4n.Core.Shapes;
using System;
using System.Collections.Generic;
using System.IO;
using JCG = J2N.Collections.Generic;

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.
     */

    public abstract class StrategyTestCase : SpatialTestCase
    {
        public const string RESOURCE_PATH = "Test_Files.";
        public const string DATA_RESOURCE_PATH = RESOURCE_PATH + "Data.";

        public static readonly String DATA_SIMPLE_BBOX = "simple-bbox.txt";
        public static readonly String DATA_STATES_POLY = "states-poly.txt";
        public static readonly String DATA_STATES_BBOX = "states-bbox.txt";
        public static readonly String DATA_COUNTRIES_POLY = "countries-poly.txt";
        public static readonly String DATA_COUNTRIES_BBOX = "countries-bbox.txt";
        public static readonly String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt";

        public static readonly String QTEST_States_IsWithin_BBox = "states-IsWithin-BBox.txt";
        public static readonly String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt";
        public static readonly String QTEST_Cities_Intersects_BBox = "cities-Intersects-BBox.txt";
        public static readonly String QTEST_Simple_Queries_BBox = "simple-Queries-BBox.txt";

        //private Logger log = Logger.getLogger(getClass().getName());

        protected readonly SpatialArgsParser argsParser = new SpatialArgsParser();

        protected SpatialStrategy strategy;
        protected bool storeShape = true;

        protected virtual void executeQueries(SpatialMatchConcern concern, params string[] testQueryFile)
        {
            //log.info("testing queried for strategy "+strategy);
            foreach (String path in testQueryFile)
            {
                IEnumerator<SpatialTestQuery> testQueryIterator = getTestQueries(path, ctx);
                runTestQueries(testQueryIterator, concern);
            }
        }

        protected virtual void getAddAndVerifyIndexedDocuments(String testDataFile)
        {
            List<Document> testDocuments = getDocuments(testDataFile);
            addDocumentsAndCommit(testDocuments);
            VerifyDocumentsIndexed(testDocuments.size());
        }

        protected virtual List<Document> getDocuments(String testDataFile)
        {
            return getDocuments(getSampleData(testDataFile));
        }

        protected virtual List<Document> getDocuments(IEnumerator<SpatialTestData> sampleData)
        {
            List<Document> documents = new List<Document>();
            while (sampleData.MoveNext())
            {
                SpatialTestData data = sampleData.Current;
                Document document = new Document();
                document.Add(new StringField("id", data.id, Field.Store.YES));
                document.Add(new StringField("name", data.name, Field.Store.YES));
                IShape shape = data.shape;
                shape = convertShapeFromGetDocuments(shape);
                if (shape != null)
                {
                    foreach (Field f in strategy.CreateIndexableFields(shape))
                    {
                        document.Add(f);
                    }
                    if (storeShape)//just for diagnostics
                        document.Add(new StoredField(strategy.FieldName, shape.toString()));
                }

                documents.Add(document);
            }
            return documents;
        }

        /** Subclasses may override to transform or remove a shape for indexing */
        protected virtual IShape convertShapeFromGetDocuments(IShape shape)
        {
            return shape;
        }

        protected virtual IEnumerator<SpatialTestData> getSampleData(String testDataFile)
        {
            String path = DATA_RESOURCE_PATH + testDataFile;
            Stream stream = GetType().getResourceAsStream(path);
            if (stream == null)
                throw new FileNotFoundException("classpath resource not found: " + path);
            return SpatialTestData.GetTestData(stream, ctx);//closes the InputStream
        }

        protected virtual IEnumerator<SpatialTestQuery> getTestQueries(String testQueryFile, SpatialContext ctx)
        {
            Stream @in = GetType().getResourceAsStream(RESOURCE_PATH + testQueryFile);
            return SpatialTestQuery.GetTestQueries(
                argsParser, ctx, testQueryFile, @in);//closes the InputStream
        }

        public virtual void runTestQueries(
            IEnumerator<SpatialTestQuery> queries,
            SpatialMatchConcern concern)
        {
            while (queries.MoveNext())
            {
                SpatialTestQuery q = queries.Current;
                runTestQuery(concern, q);
            }
        }

        public virtual void runTestQuery(SpatialMatchConcern concern, SpatialTestQuery q)
        {
            String msg = q.toString(); //"Query: " + q.args.toString(ctx);
            SearchResults got = executeQuery(makeQuery(q), Math.Max(100, q.ids.size() + 1));
            if (storeShape && got.numFound > 0)
            {
                //check stored value is there
                assertNotNull(got.results[0].document.Get(strategy.FieldName));
            }
            if (concern.orderIsImportant)
            {
                IEnumerator<String> ids = q.ids.GetEnumerator();
                foreach (SearchResult r in got.results)
                {
                    String id = r.document.Get("id");
                    if (!ids.MoveNext())
                    {
                        fail(msg + " :: Did not get enough results.  Expect" + q.ids + ", got: " + got.toDebugString());
                    }
                    assertEquals("out of order: " + msg, ids.Current, id);
                }

                if (ids.MoveNext())
                {
                    fail(msg + " :: expect more results then we got: " + ids.Current);
                }
            }
            else
            {
                // We are looking at how the results overlap
                if (concern.resultsAreSuperset)
                {
                    ISet<string> found = new JCG.HashSet<string>();
                    foreach (SearchResult r in got.results)
                    {
                        found.add(r.document.Get("id"));
                    }
                    foreach (String s in q.ids)
                    {
                        if (!found.contains(s))
                        {
                            fail("Results are mising id: " + s + " :: " + found);
                        }
                    }
                }
                else
                {
                    List<string> found = new List<string>();
                    foreach (SearchResult r in got.results)
                    {
                        found.Add(r.document.Get("id"));
                    }

                    // sort both so that the order is not important
                    CollectionUtil.TimSort(q.ids);
                    CollectionUtil.TimSort(found);
                    assertEquals(msg, q.ids.toString(), found.toString());
                }
            }
        }

        protected virtual Query makeQuery(SpatialTestQuery q)
        {
            return strategy.MakeQuery(q.args);
        }

        protected virtual void adoc(String id, String shapeStr)
        {
            IShape shape = shapeStr == null ? null : ctx.ReadShapeFromWkt(shapeStr);
            AddDocument(newDoc(id, shape));
        }
        protected virtual void adoc(String id, IShape shape)
        {
            AddDocument(newDoc(id, shape));
        }

        protected virtual Document newDoc(String id, IShape shape)
        {
            Document doc = new Document();
            doc.Add(new StringField("id", id, Field.Store.YES));
            if (shape != null)
            {
                foreach (Field f in strategy.CreateIndexableFields(shape))
                {
                    doc.Add(f);
                }
                if (storeShape)
                    doc.Add(new StoredField(strategy.FieldName, shape.toString()));//not to be parsed; just for debug
            }
            return doc;
        }

        protected virtual void DeleteDoc(String id)
        {
            indexWriter.DeleteDocuments(new TermQuery(new Term("id", id)));
        }

        /** scores[] are in docId order */
        protected virtual void CheckValueSource(ValueSource vs, float[] scores, float delta)
        {
            FunctionQuery q = new FunctionQuery(vs);

            //    //TODO is there any point to this check?
            //    int expectedDocs[] = new int[scores.length];//fill with ascending 0....length-1
            //    for (int i = 0; i < expectedDocs.length; i++) {
            //      expectedDocs[i] = i;
            //    }
            //    CheckHits.checkHits(Random, q, "", indexSearcher, expectedDocs);

            TopDocs docs = indexSearcher.Search(q, 1000);//calculates the score
            for (int i = 0; i < docs.ScoreDocs.Length; i++)
            {
                ScoreDoc gotSD = docs.ScoreDocs[i];
                float expectedScore = scores[gotSD.Doc];
                assertEquals("Not equal for doc " + gotSD.Doc, expectedScore, gotSD.Score, delta);
            }

            CheckHits.CheckExplanations(q, "", indexSearcher);
        }

        protected virtual void AssertOperation(IDictionary<String, IShape> indexedDocs,
                                       SpatialOperation operation, IShape queryShape)
        {
            //Generate truth via brute force
            ISet<string> expectedIds = new JCG.HashSet<string>();
            foreach (var stringShapeEntry in indexedDocs)
            {
                if (operation.Evaluate(stringShapeEntry.Value, queryShape))
                    expectedIds.add(stringShapeEntry.Key);
            }

            SpatialTestQuery testQuery = new SpatialTestQuery();
            testQuery.args = new SpatialArgs(operation, queryShape);
            testQuery.ids = new List<string>(expectedIds);
            runTestQuery(SpatialMatchConcern.FILTER, testQuery);
        }
    }
}
