﻿using J2N.Text;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Core;
using Lucene.Net.Analysis.Util;
using Lucene.Net.Documents;
using Lucene.Net.Support;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using JCG = J2N.Collections.Generic;
using Console = Lucene.Net.Util.SystemConsole;

namespace Lucene.Net.Search.Suggest.Analyzing
{
    /*
     * 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.
     */

    [SuppressCodecs("Lucene3x")]
    public class TestFreeTextSuggester : LuceneTestCase
    {
        [Test]
        public void TestBasic()
        {
            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("foo bar baz blah", 50),
                new Input("boo foo bar foo bee", 20)
            );

            Analyzer a = new MockAnalyzer(Random);
            FreeTextSuggester sug = new FreeTextSuggester(a, a, 2, (byte)0x20);
            sug.Build(new InputArrayIterator(keys));
            assertEquals(2, sug.Count);

            for (int i = 0; i < 2; i++)
            {

                // Uses bigram model and unigram backoff:
                assertEquals("foo bar/0.67 foo bee/0.33 baz/0.04 blah/0.04 boo/0.04",
                             ToString(sug.DoLookup("foo b", 10)));

                // Uses only bigram model:
                assertEquals("foo bar/0.67 foo bee/0.33",
                             ToString(sug.DoLookup("foo ", 10)));

                // Uses only unigram model:
                assertEquals("foo/0.33",
                             ToString(sug.DoLookup("foo", 10)));

                // Uses only unigram model:
                assertEquals("bar/0.22 baz/0.11 bee/0.11 blah/0.11 boo/0.11",
                             ToString(sug.DoLookup("b", 10)));

                // Try again after save/load:
                DirectoryInfo tmpDir = CreateTempDir("FreeTextSuggesterTest");
                //tmpDir.Create();

                FileInfo path = new FileInfo(Path.Combine(tmpDir.FullName, "suggester"));

                using (Stream os = new FileStream(path.FullName, FileMode.Create, FileAccess.Write))
                    sug.Store(os);

                using (Stream @is = new FileStream(path.FullName, FileMode.Open, FileAccess.Read))
                {
                    sug = new FreeTextSuggester(a, a, 2, (byte)0x20);
                    sug.Load(@is);
                }
                assertEquals(2, sug.Count);
            }
        }

        [Test]
        public void TestIllegalByteDuringBuild()
        {
            // Default separator is INFORMATION SEPARATOR TWO
            // (0x1e), so no input token is allowed to contain it
            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("foo\u001ebar baz", 50)
            );
            FreeTextSuggester sug = new FreeTextSuggester(new MockAnalyzer(Random));
            try
            {
                sug.Build(new InputArrayIterator(keys));
                fail("did not hit expected exception");
            }
            catch (ArgumentException /*iae*/)
            {
                // expected
            }
        }

        [Test]
        public void TestIllegalByteDuringQuery()
        {
            // Default separator is INFORMATION SEPARATOR TWO
            // (0x1e), so no input token is allowed to contain it
            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("foo bar baz", 50)
            );
            FreeTextSuggester sug = new FreeTextSuggester(new MockAnalyzer(Random));
            sug.Build(new InputArrayIterator(keys));

            try
            {
                sug.DoLookup("foo\u001eb", 10);
                fail("did not hit expected exception");
            }
            catch (ArgumentException /*iae*/)
            {
                // expected
            }
        }

        internal class TestWikiInputIterator : IInputIterator
        {
            private readonly LineFileDocs lfd;
            private readonly TestFreeTextSuggester outerInstance;
            private int count;

            public TestWikiInputIterator(TestFreeTextSuggester outerInstance, LineFileDocs lfd)
            {
                this.outerInstance = outerInstance;
                this.lfd = lfd;
            }

            public long Weight => 1;

            public IComparer<BytesRef> Comparer => null;

            public BytesRef Next()
            {
                Document doc;
                try
                {
                    doc = lfd.NextDoc();
                }
                catch (IOException ioe)
                {
                    throw new Exception(ioe.ToString(), ioe);
                }
                if (doc == null)
                {
                    return null;
                }
                if (count++ == 10000)
                {
                    return null;
                }
                return new BytesRef(doc.Get("body"));
            }

            public BytesRef Payload => null;

            public bool HasPayloads => false;

            public ICollection<BytesRef> Contexts => null;

            public bool HasContexts => false;
        }

        [Ignore("Ignored in Lucene")]
        public void TestWiki()
        {
            LineFileDocs lfd = new LineFileDocs(null, "/lucenedata/enwiki/enwiki-20120502-lines-1k.txt", false);
            // Skip header:
            lfd.NextDoc();
            FreeTextSuggester sug = new FreeTextSuggester(new MockAnalyzer(Random));
            sug.Build(new TestWikiInputIterator(this, lfd));
            if (Verbose)
            {
                Console.WriteLine(sug.GetSizeInBytes() + " bytes");

                IList<Lookup.LookupResult> results = sug.DoLookup("general r", 10);
                Console.WriteLine("results:");
                foreach (Lookup.LookupResult result in results)
                {
                    Console.WriteLine("  " + result);
                }
            }
        }

        // Make sure you can suggest based only on unigram model:
        [Test]
        public void TestUnigrams()
        {
            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("foo bar baz blah boo foo bar foo bee", 50)
            );

            Analyzer a = new MockAnalyzer(Random);
            FreeTextSuggester sug = new FreeTextSuggester(a, a, 1, (byte)0x20);
            sug.Build(new InputArrayIterator(keys));
            // Sorts first by count, descending, second by term, ascending
            assertEquals("bar/0.22 baz/0.11 bee/0.11 blah/0.11 boo/0.11",
                         ToString(sug.DoLookup("b", 10)));
        }

        // Make sure the last token is not duplicated
        [Test]
        public void TestNoDupsAcrossGrams()
        {
            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("foo bar bar bar bar", 50)
            );
            Analyzer a = new MockAnalyzer(Random);
            FreeTextSuggester sug = new FreeTextSuggester(a, a, 2, (byte)0x20);
            sug.Build(new InputArrayIterator(keys));
            assertEquals("foo bar/1.00",
                         ToString(sug.DoLookup("foo b", 10)));
        }

        // Lookup of just empty string produces unicode only matches:
        [Test]
        public void TestEmptyString()
        {
            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("foo bar bar bar bar", 50)
            );
            Analyzer a = new MockAnalyzer(Random);
            FreeTextSuggester sug = new FreeTextSuggester(a, a, 2, (byte)0x20);
            sug.Build(new InputArrayIterator(keys));
            try
            {
                sug.DoLookup("", 10);
                fail("did not hit exception");
            }
            catch (ArgumentException /*iae*/)
            {
                // expected
            }
        }

        internal class TestEndingHoleAnalyzer : Analyzer
        {
            protected internal override TokenStreamComponents CreateComponents(string fieldName, TextReader reader)
            {
                Tokenizer tokenizer = new MockTokenizer(reader);
                CharArraySet stopSet = StopFilter.MakeStopSet(TEST_VERSION_CURRENT, "of");
                return new TokenStreamComponents(tokenizer, new StopFilter(TEST_VERSION_CURRENT, tokenizer, stopSet));
            }
        }

        // With one ending hole, ShingleFilter produces "of _" and
        // we should properly predict from that:
        [Test]
        public void TestEndingHole()
        {
            // Just deletes "of"
            Analyzer a = new TestEndingHoleAnalyzer();

            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("wizard of oz", 50)
            );
            FreeTextSuggester sug = new FreeTextSuggester(a, a, 3, (byte)0x20);
            sug.Build(new InputArrayIterator(keys));
            assertEquals("wizard _ oz/1.00",
                         ToString(sug.DoLookup("wizard of", 10)));

            // Falls back to unigram model, with backoff 0.4 times
            // prop 0.5:
            assertEquals("oz/0.20",
                         ToString(sug.DoLookup("wizard o", 10)));
        }



        // If the number of ending holes exceeds the ngrams window
        // then there are no predictions, because ShingleFilter
        // does not produce e.g. a hole only "_ _" token:
        [Test]
        public void TestTwoEndingHoles()
        {
            // Just deletes "of"
            Analyzer a = new TestEndingHoleAnalyzer();

            IEnumerable<Input> keys = AnalyzingSuggesterTest.Shuffle(
                new Input("wizard of of oz", 50)
            );
            FreeTextSuggester sug = new FreeTextSuggester(a, a, 3, (byte)0x20);
            sug.Build(new InputArrayIterator(keys));
            assertEquals("",
                         ToString(sug.DoLookup("wizard of of", 10)));
        }

        internal class ByScoreThenKeyComparer : IComparer<Lookup.LookupResult>
        {
            public int Compare(Lookup.LookupResult a, Lookup.LookupResult b)
            {
                if (a.Value > b.Value)
                {
                    return -1;
                }
                else if (a.Value < b.Value)
                {
                    return 1;
                }
                else
                {
                    // Tie break by UTF16 sort order:
                    return ((string)a.Key).CompareToOrdinal((string)b.Key);
                }
            }
        }

        private static IComparer<Lookup.LookupResult> byScoreThenKey = new ByScoreThenKeyComparer();

        internal class TestRandomInputIterator : IInputIterator
        {
            internal int upto;
            private readonly TestFreeTextSuggester outerInstance;
            private readonly string[][] docs;

            public TestRandomInputIterator(TestFreeTextSuggester outerInstance, string[][] docs)
            {
                this.outerInstance = outerInstance;
                this.docs = docs;
            }

            public IComparer<BytesRef> Comparer => null;

            public BytesRef Next()
            {
                if (upto == docs.Length)
                {
                    return null;
                }
                else
                {
                    StringBuilder b = new StringBuilder();
                    foreach (string token in docs[upto])
                    {
                        b.Append(' ');
                        b.Append(token);
                    }
                    upto++;
                    return new BytesRef(b.ToString());
                }
            }

            public long Weight => Random.Next();

            public BytesRef Payload => null;

            public bool HasPayloads => false;

            public ICollection<BytesRef> Contexts => null;

            public bool HasContexts => false;
        }

        [Test]
        public void TestRandom()
        {
            string[] terms = new string[TestUtil.NextInt32(Random, 2, 10)];
            ISet<string> seen = new JCG.HashSet<string>();
            while (seen.size() < terms.Length)
            {
                string token = TestUtil.RandomSimpleString(Random, 1, 5);
                if (!seen.contains(token))
                {
                    terms[seen.size()] = token;
                    seen.add(token);
                }
            }

            Analyzer a = new MockAnalyzer(Random);

            int numDocs = AtLeast(10);
            long totTokens = 0;
            string[][] docs = new string[numDocs][];
            for (int i = 0; i < numDocs; i++)
            {
                docs[i] = new string[AtLeast(100)];
                if (Verbose)
                {
                    Console.Write("  doc " + i + ":");
                }
                for (int j = 0; j < docs[i].Length; j++)
                {
                    docs[i][j] = GetZipfToken(terms);
                    if (Verbose)
                    {
                        Console.Write(" " + docs[i][j]);
                    }
                }
                if (Verbose)
                {
                    Console.WriteLine();
                }
                totTokens += docs[i].Length;
            }

            int grams = TestUtil.NextInt32(Random, 1, 4);

            if (Verbose)
            {
                Console.WriteLine("TEST: " + terms.Length + " terms; " + numDocs + " docs; " + grams + " grams");
            }

            // Build suggester model:
            FreeTextSuggester sug = new FreeTextSuggester(a, a, grams, (byte)0x20);
            sug.Build(new TestRandomInputIterator(this, docs));

            // Build inefficient but hopefully correct model:
            List<IDictionary<string, int?>> gramCounts = new List<IDictionary<string, int?>>(grams);
            for (int gram = 0; gram < grams; gram++)
            {
                if (Verbose)
                {
                    Console.WriteLine("TEST: build model for gram=" + gram);
                }
                IDictionary<string, int?> model = new JCG.Dictionary<string, int?>();
                gramCounts.Add(model);
                foreach (string[] doc in docs)
                {
                    for (int i = 0; i < doc.Length - gram; i++)
                    {
                        StringBuilder b = new StringBuilder();
                        for (int j = i; j <= i + gram; j++)
                        {
                            if (j > i)
                            {
                                b.append(' ');
                            }
                            b.append(doc[j]);
                        }
                        string token = b.toString();
                        if (!model.TryGetValue(token, out int? curCount) || curCount == null)
                        {
                            model.Put(token, 1);
                        }
                        else
                        {
                            model.Put(token, 1 + curCount);
                        }
                        if (Verbose)
                        {
                            Console.WriteLine("  add '" + token + "' -> count=" + (model.TryGetValue(token, out int? count) ? (count.HasValue ? count.ToString() : "null") : ""));
                        }
                    }
                }
            }

            int lookups = AtLeast(100);
            for (int iter = 0; iter < lookups; iter++)
            {
                string[] tokens = new string[TestUtil.NextInt32(Random, 1, 5)];
                for (int i = 0; i < tokens.Length; i++)
                {
                    tokens[i] = GetZipfToken(terms);
                }

                // Maybe trim last token; be sure not to create the
                // empty string:
                int trimStart;
                if (tokens.Length == 1)
                {
                    trimStart = 1;
                }
                else
                {
                    trimStart = 0;
                }
                int trimAt = TestUtil.NextInt32(Random, trimStart, tokens[tokens.Length - 1].Length);
                tokens[tokens.Length - 1] = tokens[tokens.Length - 1].Substring(0, trimAt - 0);

                int num = TestUtil.NextInt32(Random, 1, 100);
                StringBuilder b = new StringBuilder();
                foreach (string token in tokens)
                {
                    b.append(' ');
                    b.append(token);
                }
                string query = b.toString();
                query = query.Substring(1);

                if (Verbose)
                {
                    Console.WriteLine("\nTEST: iter=" + iter + " query='" + query + "' num=" + num);
                }

                // Expected:
                List<Lookup.LookupResult> expected = new List<Lookup.LookupResult>();
                double backoff = 1.0;
                seen = new JCG.HashSet<string>();

                if (Verbose)
                {
                    Console.WriteLine("  compute expected");
                }
                for (int i = grams - 1; i >= 0; i--)
                {
                    if (Verbose)
                    {
                        Console.WriteLine("    grams=" + i);
                    }

                    if (tokens.Length < i + 1)
                    {
                        // Don't have enough tokens to use this model
                        if (Verbose)
                        {
                            Console.WriteLine("      skip");
                        }
                        continue;
                    }

                    if (i == 0 && tokens[tokens.Length - 1].Length == 0)
                    {
                        // Never suggest unigrams from empty string:
                        if (Verbose)
                        {
                            Console.WriteLine("      skip unigram priors only");
                        }
                        continue;
                    }

                    // Build up "context" ngram:
                    b = new StringBuilder();
                    for (int j = tokens.Length - i - 1; j < tokens.Length - 1; j++)
                    {
                        b.append(' ');
                        b.append(tokens[j]);
                    }
                    string context = b.toString();
                    if (context.Length > 0)
                    {
                        context = context.Substring(1);
                    }
                    if (Verbose)
                    {
                        Console.WriteLine("      context='" + context + "'");
                    }
                    long contextCount;
                    if (context.Length == 0)
                    {
                        contextCount = totTokens;
                    }
                    else
                    {
                        //int? count = gramCounts.get(i - 1).get(context);
                        var gramCount = gramCounts[i - 1];
                        if (!gramCount.TryGetValue(context, out int? count) || count == null)
                        {
                            // We never saw this context:
                            backoff *= FreeTextSuggester.ALPHA;
                            if (Verbose)
                            {
                                Console.WriteLine("      skip: never saw context");
                            }
                            continue;
                        }
                        contextCount = count.GetValueOrDefault();
                    }
                    if (Verbose)
                    {
                        Console.WriteLine("      contextCount=" + contextCount);
                    }
                    IDictionary<string, int?> model = gramCounts[i];

                    // First pass, gather all predictions for this model:
                    if (Verbose)
                    {
                        Console.WriteLine("      find terms w/ prefix=" + tokens[tokens.Length - 1]);
                    }
                    List<Lookup.LookupResult> tmp = new List<Lookup.LookupResult>();
                    foreach (string term in terms)
                    {
                        if (term.StartsWith(tokens[tokens.Length - 1], StringComparison.Ordinal))
                        {
                            if (Verbose)
                            {
                                Console.WriteLine("        term=" + term);
                            }
                            if (seen.contains(term))
                            {
                                if (Verbose)
                                {
                                    Console.WriteLine("          skip seen");
                                }
                                continue;
                            }
                            string ngram = (context + " " + term).Trim();
                            //Integer count = model.get(ngram);
                            if (model.TryGetValue(ngram, out int? count) && count != null)
                            {
                                // LUCENENET NOTE: We need to calculate this as decimal because when using double it can sometimes 
                                // return numbers that are greater than long.MaxValue, which results in a negative long number.
                                // This is also the way it is being done in the FreeTextSuggester to work around the issue.
                                Lookup.LookupResult lr = new Lookup.LookupResult(ngram, (long)(long.MaxValue * ((decimal)backoff * (decimal)count / contextCount)));
                                tmp.Add(lr);
                                if (Verbose)
                                {
                                    Console.WriteLine("      add tmp key='" + lr.Key + "' score=" + lr.Value);
                                }
                            }
                        }
                    }

                    // Second pass, trim to only top N, and fold those
                    // into overall suggestions:
                    tmp.Sort(byScoreThenKey);
                    if (tmp.size() > num)
                    {
                        //tmp.subList(num, tmp.size()).clear();
                        tmp.RemoveRange(num, tmp.size() - num);
                    }
                    foreach (Lookup.LookupResult result in tmp)
                    {
                        string key = result.Key.toString();
                        int idx = key.LastIndexOf(' ');
                        string lastToken;
                        if (idx != -1)
                        {
                            lastToken = key.Substring(idx + 1);
                        }
                        else
                        {
                            lastToken = key;
                        }
                        if (!seen.contains(lastToken))
                        {
                            seen.add(lastToken);
                            expected.Add(result);
                            if (Verbose)
                            {
                                Console.WriteLine("      keep key='" + result.Key + "' score=" + result.Value);
                            }
                        }
                    }

                    backoff *= FreeTextSuggester.ALPHA;
                }

                expected.Sort(byScoreThenKey);

                if (expected.size() > num)
                {
                    expected.RemoveRange(num, expected.size() - num);
                }

                // Actual:
                IList<Lookup.LookupResult> actual = sug.DoLookup(query, num);

                if (Verbose)
                {
                    Console.WriteLine("  expected: " + expected);
                    Console.WriteLine("    actual: " + actual);
                }

                assertEquals(expected.ToString(), actual.ToString());
            }
        }

        private static string GetZipfToken(string[] tokens)
        {
            // Zipf-like distribution:
            for (int k = 0; k < tokens.Length; k++)
            {
                if (Random.nextBoolean() || k == tokens.Length - 1)
                {
                    return tokens[k];
                }
            }
            Debug.Assert(false);
            return null;
        }

        private static string ToString(IEnumerable<Lookup.LookupResult> results)
        {
            StringBuilder b = new StringBuilder();
            foreach (Lookup.LookupResult result in results)
            {
                b.Append(' ');
                b.Append(result.Key);
                b.Append('/');
                b.AppendFormat(CultureInfo.InvariantCulture, "{0:0.00}", ((double)result.Value) / long.MaxValue);
            }
            return b.toString().Trim();
        }
    }
}
