using NUnit.Framework;
using System;
using System.Globalization;
using System.Threading;
using Assert = Lucene.Net.TestFramework.Assert;

namespace Lucene.Net.Analysis.Phonetic.Language
{
    /*
     * 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 StringEncoderAbstractTest<T>
        where T : IStringEncoder
    {
        protected T stringEncoder;

        [SetUp]
        public void SetUp()
        {
            stringEncoder = this.CreateStringEncoder();
        }

        public virtual void CheckEncoding(string expected, string source)
        {
            Assert.AreEqual(expected, this.StringEncoder.Encode(source), "Source: " + source);
        }

        protected virtual void CheckEncodings(string[][] data)
        {
            foreach (string[]
                element in data)
            {
                this.CheckEncoding(element[1], element[0]);
            }
        }

        protected virtual void CheckEncodingVariations(string expected, string[] data)
        {
            foreach (string element in data)
            {
                this.CheckEncoding(expected, element);
            }
        }

        protected abstract T CreateStringEncoder();

        public virtual T StringEncoder => this.stringEncoder;

        [Test]
        public virtual void TestEncodeEmpty()
        {
            IStringEncoder encoder = this.StringEncoder;
            encoder.Encode("");
            encoder.Encode(" ");
            encoder.Encode("\t");
        }

        // LUCENENET specific - since strings are sealed in .NET, there
        // is no point in implementing IEncoder or running these tests.
        // Our version only accepts strings
        [Test]
        public virtual void TestEncodeNull()
        {
            IStringEncoder encoder = this.StringEncoder;
            try
            {
                encoder.Encode(null);
            }
#pragma warning disable 168
            catch (/*Encoder*/Exception ee)
#pragma warning restore 168
            {
                // An exception should be thrown
            }
        }

        //[Test]
        //public virtual void TestEncodeWithInvalidObject()
        //{
        //    bool exceptionThrown = false;
        //    try
        //    {
        //        IStringEncoder encoder = this.StringEncoder;
        //        encoder.Encode(3.4f);
        //    }
        //    catch (Exception e)
        //    {
        //        exceptionThrown = true;
        //    }
        //    Assert.True(exceptionThrown, "An exception was not thrown when we tried to encode " + "a Float object");
        //}

        [Test]
        public virtual void TestLocaleIndependence()
        {
            IStringEncoder encoder = this.StringEncoder;

            string[]
            data = { "I", "i", };

            CultureInfo orig = CultureInfo.CurrentCulture;
            CultureInfo[] locales = { new CultureInfo("en"), new CultureInfo("tr"), CultureInfo.CurrentCulture };

            try
            {
                foreach (string element in data)
                {
                    string @ref = null;
                    for (int j = 0; j < locales.Length; j++)
                    {
                        //Locale.setDefault(locales[j]);
#if FEATURE_CULTUREINFO_CURRENTCULTURE_SETTER
                        CultureInfo.CurrentCulture = locales[j];
#else
                        Thread.CurrentThread.CurrentCulture = locales[j];
#endif
                        if (j <= 0)
                        {
                            @ref = encoder.Encode(element);
                        }
                        else
                        {
                            string cur = null;
                            try
                            {
                                cur = encoder.Encode(element);
                            }
                            catch (Exception e)
                            {
                                Assert.Fail(CultureInfo.CurrentCulture.ToString() + ": " + e.Message);
                            }
                            Assert.AreEqual(@ref, cur, CultureInfo.CurrentCulture.ToString() + ": ");
                        }
                    }
                }
            }
            finally
            {
                //Locale.setDefault(orig);
#if FEATURE_CULTUREINFO_CURRENTCULTURE_SETTER
                CultureInfo.CurrentCulture = orig;
#else
                Thread.CurrentThread.CurrentCulture = orig;
#endif
            }
        }
    }
}
