﻿using J2N;
using J2N.Threading;
using Lucene.Net.Attributes;
using Lucene.Net.Support;
using Lucene.Net.Util;
using NUnit.Framework;
using System;
using System.IO;
using System.Threading;
using Assert = Lucene.Net.TestFramework.Assert;
using Console = Lucene.Net.Util.SystemConsole;

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

    using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
    using TestUtil = Lucene.Net.Util.TestUtil;

    [TestFixture]
    public class TestDirectory : LuceneTestCase
    {
        [Test]
        public virtual void TestDetectClose()
        {
            DirectoryInfo tempDir = CreateTempDir(GetType().Name);
            Directory[] dirs = new Directory[] { new RAMDirectory(), new SimpleFSDirectory(tempDir), new NIOFSDirectory(tempDir) };

            foreach (Directory dir in dirs)
            {
                dir.Dispose();
                try
                {
                    dir.CreateOutput("test", NewIOContext(Random));
                    Assert.Fail("did not hit expected exception");
                }
#pragma warning disable 168
                catch (ObjectDisposedException ace)
#pragma warning restore 168
                {
                }
            }
        }

        // test is occasionally very slow, i dont know why
        // try this seed: 7D7E036AD12927F5:93333EF9E6DE44DE
        [Test]
        [Slow]
        //[Nightly] // This was marked Nightly in Java, but we are not seeing very bad performance, so leaving it in the normal flow
        public virtual void TestThreadSafety()
        {
            BaseDirectoryWrapper dir = NewDirectory();
            dir.CheckIndexOnDispose = false; // we arent making an index
            if (dir is MockDirectoryWrapper)
            {
                ((MockDirectoryWrapper)dir).Throttling = Throttling.NEVER; // makes this test really slow
            }

            if (Verbose)
            {
                Console.WriteLine(dir);
            }

            TheThread theThread = new TheThread("t1", dir);
            TheThread2 theThread2 = new TheThread2("t2", dir);
            theThread.Start();
            theThread2.Start();

            theThread.Join();
            theThread2.Join();

            dir.Dispose();
        }

        private class TheThread : ThreadJob
        {
            private readonly string name;
            private readonly BaseDirectoryWrapper outerBDWrapper;

            public TheThread(string name, BaseDirectoryWrapper baseDirectoryWrapper)
            {
                this.name = name;
                outerBDWrapper = baseDirectoryWrapper;
            }

            public override void Run()
            {
                for (int i = 0; i < 3000; ++i)
                {
                    string fileName = this.name + i;

                    try
                    {
                        using (IndexOutput output = outerBDWrapper.CreateOutput(fileName, NewIOContext(Random))) { }
                        Assert.IsTrue(SlowFileExists(outerBDWrapper, fileName));
                    }
                    catch (IOException e)
                    {
                        throw new Exception(e.ToString(), e);
                    }
                }
            }
        }

        private class TheThread2 : ThreadJob
        {
            private string name;
            private readonly BaseDirectoryWrapper outerBDWrapper;

            public TheThread2(string name, BaseDirectoryWrapper baseDirectoryWrapper)
            {
                this.name = name;
                outerBDWrapper = baseDirectoryWrapper;
            }

            public override void Run()
            {
                for (int i = 0; i < 10000; i++)
                {
                    try
                    {
                        string[] files = outerBDWrapper.ListAll();
                        foreach (string file in files)
                        {
                            try
                            {
                                using IndexInput input = outerBDWrapper.OpenInput(file, NewIOContext(Random));
                            }
#pragma warning disable 168
                            catch (FileNotFoundException fne)
#pragma warning restore 168
                            {
                            }
                            // LUCENENET specific - since NoSuchDirectoryException subclasses FileNotFoundException
                            // in Lucene, we need to catch it here to be on the safe side.
                            catch (DirectoryNotFoundException)
                            {
                            }
                            catch (IOException e)
                            {
                                if (!e.Message.Contains("still open for writing"))
                                {
                                    throw new Exception(e.ToString(), e);
                                }
                            }
                            if (Random.NextBoolean())
                            {
                                break;
                            }
                        }
                    }
                    catch (IOException e)
                    {
                        throw new Exception(e.ToString(), e);
                    }
                }
            }
        }

        // Test that different instances of FSDirectory can coexist on the same
        // path, can read, write, and lock files.
        [Test]
        public virtual void TestDirectInstantiation()
        {
            DirectoryInfo path = CreateTempDir("testDirectInstantiation");

            byte[] largeBuffer = new byte[Random.Next(256 * 1024)], largeReadBuffer = new byte[largeBuffer.Length];
            for (int i = 0; i < largeBuffer.Length; i++)
            {
                largeBuffer[i] = (byte)i; // automatically loops with modulo
            }

            var dirs = new FSDirectory[] { new SimpleFSDirectory(path, null), new NIOFSDirectory(path, null), new MMapDirectory(path, null) };

            for (int i = 0; i < dirs.Length; i++)
            {
                FSDirectory dir = dirs[i];
                dir.EnsureOpen();
                string fname = "foo." + i;
                string lockname = "foo" + i + ".lck";
                IndexOutput @out = dir.CreateOutput(fname, NewIOContext(Random));
                @out.WriteByte((byte)i);
                @out.WriteBytes(largeBuffer, largeBuffer.Length);
                @out.Dispose();

                for (int j = 0; j < dirs.Length; j++)
                {
                    FSDirectory d2 = dirs[j];
                    d2.EnsureOpen();
                    Assert.IsTrue(SlowFileExists(d2, fname));
                    Assert.AreEqual(1 + largeBuffer.Length, d2.FileLength(fname));

                    // LUCENENET specific - unmap hack not needed
                    //// don't do read tests if unmapping is not supported!
                    //if (d2 is MMapDirectory && !((MMapDirectory)d2).UseUnmap)
                    //{
                    //    continue;
                    //}

                    IndexInput input = d2.OpenInput(fname, NewIOContext(Random));
                    Assert.AreEqual((byte)i, input.ReadByte());
                    // read array with buffering enabled
                    Arrays.Fill(largeReadBuffer, (byte)0);
                    input.ReadBytes(largeReadBuffer, 0, largeReadBuffer.Length, true);
                    Assert.AreEqual(largeBuffer, largeReadBuffer);
                    // read again without using buffer
                    input.Seek(1L);
                    Arrays.Fill(largeReadBuffer, (byte)0);
                    input.ReadBytes(largeReadBuffer, 0, largeReadBuffer.Length, false);
                    Assert.AreEqual(largeBuffer, largeReadBuffer);
                    input.Dispose();
                }

                // delete with a different dir
                dirs[(i + 1) % dirs.Length].DeleteFile(fname);

                for (int j = 0; j < dirs.Length; j++)
                {
                    FSDirectory d2 = dirs[j];
                    Assert.IsFalse(SlowFileExists(d2, fname));
                }

                Lock @lock = dir.MakeLock(lockname);
                Assert.IsTrue(@lock.Obtain());

                for (int j = 0; j < dirs.Length; j++)
                {
                    FSDirectory d2 = dirs[j];
                    Lock lock2 = d2.MakeLock(lockname);
                    try
                    {
                        Assert.IsFalse(lock2.Obtain(1));
                    }
#pragma warning disable 168
                    catch (LockObtainFailedException e)
#pragma warning restore 168
                    {
                        // OK
                    }
                }

                @lock.Dispose();

                // now lock with different dir
                @lock = dirs[(i + 1) % dirs.Length].MakeLock(lockname);
                Assert.IsTrue(@lock.Obtain());
                @lock.Dispose();
            }

            for (int i = 0; i < dirs.Length; i++)
            {
                FSDirectory dir = dirs[i];
                dir.EnsureOpen();
                dir.Dispose();
                Assert.IsFalse(dir.IsOpen);
            }
        }

        // LUCENE-1464
        [Test]
        public virtual void TestDontCreate()
        {
            var parentFolder = CreateTempDir(this.GetType().Name.ToLowerInvariant());
            var path = new DirectoryInfo(Path.Combine(parentFolder.FullName, "doesnotexist"));
            try
            {
                Assert.IsTrue(!path.Exists);
                Directory dir = new SimpleFSDirectory(path, null);
                Assert.IsTrue(!path.Exists);
                dir.Dispose();
            }
            finally
            {
                if (path.Exists) System.IO.Directory.Delete(path.FullName, true);
            }
        }

        // LUCENE-1468
        [Test]
        public virtual void TestRAMDirectoryFilter()
        {
            CheckDirectoryFilter(new RAMDirectory());
        }

        // LUCENE-1468
        [Test]
        public virtual void TestFSDirectoryFilter()
        {
            CheckDirectoryFilter(NewFSDirectory(CreateTempDir("test")));
        }

        private static bool ContainsFile(Directory directory, string file) // LUCENENET specific method to prevent having to use Arrays.AsList(), which creates unnecessary memory allocations
        {
            return Array.IndexOf(directory.ListAll(), file) > -1;
        }

        // LUCENE-1468
        private void CheckDirectoryFilter(Directory dir)
        {
            string name = "file";
            try
            {
                dir.CreateOutput(name, NewIOContext(Random)).Dispose();
                Assert.IsTrue(SlowFileExists(dir, name));
                Assert.IsTrue(ContainsFile(dir, name));
            }
            finally
            {
                dir.Dispose();
            }
        }

        // LUCENE-1468
        [Test]
        public virtual void TestCopySubdir()
        {
            DirectoryInfo path = CreateTempDir("testsubdir");
            try
            {
                //path.mkdirs();
                System.IO.Directory.CreateDirectory(path.FullName);
                //(new File(path, "subdir")).mkdirs();
                System.IO.Directory.CreateDirectory(new DirectoryInfo(Path.Combine(path.FullName, "subdir")).FullName);
                Directory fsDir = new SimpleFSDirectory(path, null);
                Assert.AreEqual(0, (new RAMDirectory(fsDir, NewIOContext(Random))).ListAll().Length);
            }
            finally
            {
                System.IO.Directory.Delete(path.FullName, true);
            }
        }

        // LUCENE-1468
        [Test]
        public virtual void TestNotDirectory()
        {
            DirectoryInfo path = CreateTempDir("testnotdir");
            Directory fsDir = new SimpleFSDirectory(path, null);
            try
            {
                IndexOutput @out = fsDir.CreateOutput("afile", NewIOContext(Random));
                @out.Dispose();
                Assert.IsTrue(SlowFileExists(fsDir, "afile"));
                try
                {
                    var d = new SimpleFSDirectory(new DirectoryInfo(Path.Combine(path.FullName, "afile")), null);
                    Assert.Fail("did not hit expected exception");
                }
#pragma warning disable 168
                catch (DirectoryNotFoundException nsde)
#pragma warning restore 168
                {
                    // Expected
                }
            }
            finally
            {
                fsDir.Dispose();
                System.IO.Directory.Delete(path.FullName, true);
            }
        }

        [Test]
        public virtual void TestFsyncDoesntCreateNewFiles()
        {
            var path = CreateTempDir("nocreate");
            Console.WriteLine(path.FullName);

            using Directory fsdir = new SimpleFSDirectory(path);
            // write a file
            using (var o = fsdir.CreateOutput("afile", NewIOContext(Random)))
            {
                o.WriteString("boo");
            }

            // delete it
            try
            {
                File.Delete(Path.Combine(path.FullName, "afile"));
            }
            catch (Exception e)
            {
                Assert.Fail("Deletion of new Directory should never fail.\nException thrown: {0}", e);
            }

            // directory is empty
            Assert.AreEqual(0, fsdir.ListAll().Length);


            // LUCENENET specific: Since FSDirectory.Sync() does not actually do anything in .NET
            // we decided to remove the exception as well. This is safe to ignore here.
            //// fsync it
            //try
            //{
            //    fsdir.Sync(Collections.Singleton("afile"));
            //    Assert.Fail("didn't get expected exception, instead fsync created new files: " +
            //                Collections.ToString(fsdir.ListAll()));
            //}
            //catch (FileNotFoundException)
            //{
            //    // ok
            //}
            //// LUCENENET specific - since NoSuchDirectoryException subclasses FileNotFoundException
            //// in Lucene, we need to catch it here to be on the safe side.
            //catch (DirectoryNotFoundException)
            //{
            //    // ok
            //}

            // directory is still empty
            Assert.AreEqual(0, fsdir.ListAll().Length);
        }

        [Test]
        [Slow]
        [LuceneNetSpecific]
        public virtual void ConcurrentIndexAccessThrowsWithoutSynchronizedStaleFiles()
        {
            DirectoryInfo tempDir = CreateTempDir(GetType().Name);
            using Directory dir = new SimpleFSDirectory(tempDir);
            var ioContext = NewIOContext(Random);
            var threads = new Thread[Environment.ProcessorCount];
            int file = 0;
            Exception exception = null;
            bool stopped = false;

            using (var @event = new ManualResetEvent(false))
            {
                for (int i = 0; i < threads.Length; i++)
                {
                    var thread = new Thread(() =>
                    {
                        while (!stopped)
                        {
                            int nextFile = Interlocked.Increment(ref file);
                            try
                            {
                                dir.CreateOutput("test" + nextFile, ioContext).Dispose();
                            }
                            catch (Exception ex)
                            {
                                exception = ex;
                                @event.Set();
                                break;
                            }
                        }
                    });
                    thread.Start();
                    threads[i] = thread;
                }

                bool raised = @event.WaitOne(TimeSpan.FromSeconds(5));

                stopped = true;

                if (raised)
                    throw new Exception("Test failed", exception);
            }

            foreach (var thread in threads)
            {
                thread.Join();
            }
        }


#pragma warning disable 612, 618
        [Test]
        [LuceneNetSpecific]
        public void TestLUCENENET521()
        {
            var newDirectoryInfo = CreateTempDir("LUCENENET521");
            using (var zipFileStream = this.GetType().FindAndGetManifestResourceStream("LUCENENET521.zip"))
            {
                TestUtil.Unzip(zipFileStream, newDirectoryInfo);
            }

            var newDirectory = new MMapDirectory(newDirectoryInfo);
            var conf = new Index.IndexWriterConfig(LuceneVersion.LUCENE_30, new Analysis.Standard.StandardAnalyzer(LuceneVersion.LUCENE_30));
            var indexWriter = new Index.IndexWriter(newDirectory, conf);
            indexWriter.Dispose();

            var sharedReader = Index.IndexReader.Open(newDirectory /*, true*/);
            const int times = 10;
            const int concurrentTaskCount = 10;
            var task = new System.Threading.Tasks.Task[concurrentTaskCount];
            for (int i = 0; i < concurrentTaskCount; i++)
            {
                task[i] = new System.Threading.Tasks.Task(() => Search(sharedReader, times));
                task[i].Start();
            }

            System.Threading.Tasks.Task.WaitAll(task);
            return;
        }
#pragma warning restore 612, 618

        private static void Search(Index.IndexReader r, int times)
        {
            var searcher = new Search.IndexSearcher(r);
            var docs = new System.Collections.Generic.List<Documents.Document>(10000);
            for (int i = 0; i < times; i++)
            {
                var q = new Search.TermQuery(new Index.Term("title", "volume"));
                foreach (var scoreDoc in searcher.Search(q, 100).ScoreDocs)
                {
                    docs.Add(searcher.Doc(scoreDoc.Doc));
                }
            }
        }
    }
}