﻿using Lucene.Net.Util;
using NUnit.Framework;
using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace Lucene.Net.Demo
{
    /*
     * 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 class TestDemo : LuceneTestCase
    {
        private void TestOneSearch(DirectoryInfo indexPath, string query, int expectedHitCount)
        {
            TextWriter outSave = Console.Out;
            try
            {
                MemoryStream bytes = new MemoryStream();
                // .NET NOTE: GetEncoding(0) returns the current system's default encoding
                var fakeSystemOut = new StreamWriter(bytes, Encoding.GetEncoding(0));
                Console.SetOut(fakeSystemOut);
                // LUCENENET specific: changed the arguments to act more like the dotnet.exe commands.
                // * only optional arguments start with - 
                // * options have a long form that starts with --
                // * required arguments must be supplied without - or -- and in a specific order
                // Since the demo is meant to be seen by end users, these changes were necessary to make
                // it consistent with the lucene-cli utility.
                SearchFiles.Main(new string[] { indexPath.FullName, "--query", query });
                fakeSystemOut.Flush();
                // .NET NOTE: GetEncoding(0) returns the current system's default encoding
                string output = Encoding.GetEncoding(0).GetString(bytes.ToArray()); // intentionally use default encoding
                assertTrue("output=" + output, output.Contains(expectedHitCount + " total matching documents"));
            }
            finally
            {
                Console.SetOut(outSave);
            }
        }

        [Test]
        public void TestIndexSearch()
        {
            DirectoryInfo filesDir = CreateTempDir("DemoTestFiles");

            // LUCENENET specific - rather than relying on a flakey
            // file location, we first extract the files to the disk
            // from embedded resources. Then we know the exact location
            // where they are and it can't fail.
            var thisAssembly = this.GetType().Assembly;
            string embeddedDocsLocation = "Test_Files.Docs.";
            foreach (var file in thisAssembly.GetManifestResourceNames())
            {
                if (file.Contains(embeddedDocsLocation))
                {
                    string fileName = Regex.Replace(file, ".*" + embeddedDocsLocation.Replace(".", @"\."), "");
                    string destinationPath = Path.Combine(filesDir.FullName, fileName);

                    using Stream input = thisAssembly.GetManifestResourceStream(file);
                    using Stream output = new FileStream(destinationPath, FileMode.Create, FileAccess.Write);
                    input.CopyTo(output);
                }
            }

            DirectoryInfo indexDir = CreateTempDir("DemoTest");
            // LUCENENET specific: changed the arguments to act more like the dotnet.exe commands.
            // * only optional arguments start with - 
            // * options have a long form that starts with --
            // * required arguments must be supplied without - or -- and in a specific order
            // Since the demo is meant to be seen by end users, these changes were necessary to make
            // it consistent with the lucene-cli utility.
            // NOTE: There is no -create in lucene, but it has the same effect as if --update were left out
            IndexFiles.Main(new string[] { indexDir.FullName, filesDir.FullName }); 
            //IndexFiles.Main(new string[] { "-create", "-docs", filesDir.FullName, "-index", indexDir.FullName });
            TestOneSearch(indexDir, "apache", 3);
            TestOneSearch(indexDir, "patent", 8);
            TestOneSearch(indexDir, "lucene", 0);
            TestOneSearch(indexDir, "gnu", 6);
            TestOneSearch(indexDir, "derivative", 8);
            TestOneSearch(indexDir, "license", 13);
        }
    }
}
