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

// Add NuGet References:

// Lucene.Net.Analysis.Common
// Lucene.Net.QueryParser

using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers.Classic;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;
using System;
using System.Globalization;
using System.IO;
using System.Text;

namespace Lucene.Net.Demo
{
    /// <summary>
    /// Simple command-line based search demo.
    /// </summary>
    public static class SearchFiles // LUCENENET specific: CA1052 Static holder types should be Static or NotInheritable
    {
        /// <summary>Simple command-line based search demo.</summary>
        public static void Main(string[] args)
        {
            // The <CONSOLE_APP_NAME> should be the assembly name of the application
            // this code is compiled into. In .NET Framework, it is the name of the EXE file.
            // In .NET Core, you have the option of compiling this into either a DLL or an EXE  
            // (see https://docs.microsoft.com/en-us/dotnet/core/deploying/index).
            // In the first case, the <CONSOLE_APP_NAME> will be "dotnet <DLL_NAME>.dll".
            string usage = "Usage: <CONSOLE_APP_NAME> <INDEX_DIRECTORY> [-f|--field <FIELD>] " +
                "[-r|--repeat <NUMBER>] [-qf|--queries-file <PATH>] [-q|--query <QUERY>] " +
                "[--raw] [-p|--page-size <NUMBER>]\n\n" +
                "Use no --query or --queries-file option for interactive mode.\n\n" +
                "See http://lucene.apache.org/core/4_8_0/demo/ for details.";
            if (args.Length < 1 || args.Length > 0 && 
                ("?".Equals(args[0], StringComparison.Ordinal) || "-h".Equals(args[0], StringComparison.Ordinal) || "--help".Equals(args[0], StringComparison.Ordinal)))
            {
                Console.WriteLine(usage);
                Environment.Exit(0);
            }

            string index = args[0];
            string field = "contents";
            string queries = null;
            int repeat = 0;
            bool raw = false;
            string queryString = null;
            int hitsPerPage = 10;

            for (int i = 0; i < args.Length; i++)
            {
                if ("-f".Equals(args[i], StringComparison.Ordinal) || "-field".Equals(args[i], StringComparison.Ordinal))
                {
                    field = args[i + 1];
                    i++;
                }
                else if ("-qf".Equals(args[i], StringComparison.Ordinal) || "--queries-file".Equals(args[i], StringComparison.Ordinal))
                {
                    queries = args[i + 1];
                    i++;
                }
                else if ("-q".Equals(args[i], StringComparison.Ordinal) || "--query".Equals(args[i], StringComparison.Ordinal))
                {
                    queryString = args[i + 1];
                    i++;
                }
                else if ("-r".Equals(args[i], StringComparison.Ordinal) || "--repeat".Equals(args[i], StringComparison.Ordinal))
                {
                    repeat = int.Parse(args[i + 1], CultureInfo.InvariantCulture);
                    i++;
                }
                else if ("--raw".Equals(args[i], StringComparison.Ordinal))
                {
                    raw = true;
                }
                else if ("-p".Equals(args[i], StringComparison.Ordinal) || "--paging".Equals(args[i], StringComparison.Ordinal))
                {
                    hitsPerPage = int.Parse(args[i + 1], CultureInfo.InvariantCulture);
                    if (hitsPerPage <= 0)
                    {
                        Console.WriteLine("There must be at least 1 hit per page.");
                        Environment.Exit(1);
                    }
                    i++;
                }
            }

            using IndexReader reader = DirectoryReader.Open(FSDirectory.Open(index));
            IndexSearcher searcher = new IndexSearcher(reader);
            // :Post-Release-Update-Version.LUCENE_XY:
            Analyzer analyzer = new StandardAnalyzer(LuceneVersion.LUCENE_48);

            TextReader input = null;
            if (queries != null)
            {
                input = new StreamReader(new FileStream(queries, FileMode.Open, FileAccess.Read), Encoding.UTF8);
            }
            else
            {
                input = Console.In;
            }
            // :Post-Release-Update-Version.LUCENE_XY:
            QueryParser parser = new QueryParser(LuceneVersion.LUCENE_48, field, analyzer);
            while (true)
            {
                if (queries == null && queryString == null)
                {
                    // prompt the user
                    Console.WriteLine("Enter query (or press Enter to exit): ");
                }

                string line = queryString ?? input.ReadLine();

                if (line == null || line.Length == 0)
                {
                    break;
                }

                line = line.Trim();
                if (line.Length == 0)
                {
                    break;
                }

                Query query = parser.Parse(line);
                Console.WriteLine("Searching for: " + query.ToString(field));

                if (repeat > 0) // repeat & time as benchmark
                {
                    DateTime start = DateTime.UtcNow;
                    for (int i = 0; i < repeat; i++)
                    {
                        searcher.Search(query, null, 100);
                    }
                    DateTime end = DateTime.UtcNow;
                    Console.WriteLine("Time: " + (end - start).TotalMilliseconds + "ms");
                }

                DoPagingSearch(searcher, query, hitsPerPage, raw, queries == null && queryString == null);

                if (queryString != null)
                {
                    break;
                }
            }
        }

        /// <summary>
        /// This demonstrates a typical paging search scenario, where the search engine presents 
        /// pages of size n to the user. The user can then go to the next page if interested in
        /// the next hits.
        /// <para/>
        /// When the query is executed for the first time, then only enough results are collected
        /// to fill 5 result pages. If the user wants to page beyond this limit, then the query
        /// is executed another time and all hits are collected.
        /// </summary>
        public static void DoPagingSearch(IndexSearcher searcher, Query query,
                                           int hitsPerPage, bool raw, bool interactive)
        {
            // Collect enough docs to show 5 pages
            TopDocs results = searcher.Search(query, 5 * hitsPerPage);
            ScoreDoc[]
            hits = results.ScoreDocs;

            int numTotalHits = results.TotalHits;
            Console.WriteLine(numTotalHits + " total matching documents");

            int start = 0;
            int end = Math.Min(numTotalHits, hitsPerPage);

            while (true)
            {
                if (end > hits.Length)
                {
                    Console.WriteLine("Only results 1 - " + hits.Length + " of " + numTotalHits + " total matching documents collected.");
                    Console.WriteLine("Collect more (y/n) ?");
                    var key = Console.ReadKey().KeyChar;
                    if (key == 'n')
                    {
                        break;
                    }

                    hits = searcher.Search(query, numTotalHits).ScoreDocs;
                }

                end = Math.Min(hits.Length, start + hitsPerPage);

                for (int i = start; i < end; i++)
                {
                    if (raw) // output raw format
                    {                   
                        Console.WriteLine("doc=" + hits[i].Doc + " score=" + hits[i].Score);
                        continue;
                    }

                    Document doc = searcher.Doc(hits[i].Doc);
                    string path = doc.Get("path");
                    if (path != null)
                    {
                        Console.WriteLine((i + 1) + ". " + path);
                        string title = doc.Get("title");
                        if (title != null)
                        {
                            Console.WriteLine("   Title: " + doc.Get("title"));
                        }
                    }
                    else
                    {
                        Console.WriteLine((i + 1) + ". " + "No path for this document");
                    }

                }

                if (!interactive || end == 0)
                {
                    break;
                }

                if (numTotalHits >= end)
                {
                    var pageNumberBuilder = new StringBuilder();
                    bool quit = false;
                    while (true)
                    {
                        if (pageNumberBuilder.Length == 0)
                        {
                            Console.WriteLine("Press ");
                            if (start - hitsPerPage >= 0)
                            {
                                Console.WriteLine("(p)revious page, ");
                            }
                            if (start + hitsPerPage < numTotalHits)
                            {
                                Console.WriteLine("(n)ext page, ");
                            }
                            Console.WriteLine("(q)uit or enter number to jump to a page.");
                        }
                        var key = Console.ReadKey(intercept: true).KeyChar;
                        if (key == 'q')
                        {
                            quit = true;
                            break;
                        }
                        if (key == 'p')
                        {
                            start = Math.Max(0, start - hitsPerPage);
                            break;
                        }
                        else if (key == 'n')
                        {
                            if (start + hitsPerPage < numTotalHits)
                            {
                                start += hitsPerPage;
                            }
                            break;
                        }
                        else if (key == (char)13) // enter key
                        {
                            Console.WriteLine();
                            int page = int.Parse(pageNumberBuilder.ToString(), CultureInfo.InvariantCulture);
                            pageNumberBuilder.Clear();
                            if ((page - 1) * hitsPerPage < numTotalHits)
                            {
                                start = (page - 1) * hitsPerPage;
                                break;
                            }
                            else
                            {
                                Console.WriteLine("No such page");
                            }
                        }
                        else if (char.IsDigit(key))
                        {
                            Console.Write(key);
                            pageNumberBuilder.Append(key);
                        }
                        else
                        {
                            Console.WriteLine("No such command");
                        }
                    }
                    if (quit) break;
                    end = Math.Min(numTotalHits, start + hitsPerPage);
                }
            }
        }
    }
}
