﻿// 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 System;
using System.Collections.Generic;
using Org.Apache.REEF.Tang.Annotations;
using Org.Apache.REEF.Tang.Exceptions;
using Org.Apache.REEF.Tang.Formats;
using Org.Apache.REEF.Tang.Implementations.Tang;
using Org.Apache.REEF.Tang.Interface;
using Org.Apache.REEF.Tang.Util;
using Xunit;

namespace Org.Apache.REEF.Tang.Tests.Format
{
    public interface IFoo
    {
        int getFooness();
    }

    interface ISuper
    {
    }

    public class TestConfigurationModule
    {
        [Fact]
        public void SmokeTest() 
        {
            // Here we set some configuration values.  In true tang style,
            // you won't be able to set them more than once ConfigurationModule's
            // implementation is complete.
            Type fooType = typeof(Org.Apache.REEF.Tang.Tests.Format.IFoo);
            
            IConfiguration c = MyConfigurationModule.Conf
                .Set(MyConfigurationModule.TheFoo, GenericType<FooImpl>.Class)
                .Set(MyConfigurationModule.FooNess, "12")
                .Build();
                IFoo f = (IFoo)TangFactory.GetTang().NewInjector(c).GetInstance(fooType);
                Assert.Equal(f.getFooness(), 12);
          }

        [Fact]
        public void SmokeTestConfig()
        {
            // Here we set some configuration values.  In true tang style,
            // you won't be able to set them more than once ConfigurationModule's
            // implementation is complete.
            Type fooType = typeof(Org.Apache.REEF.Tang.Tests.Format.IFoo);

            IConfiguration c = MyConfigurationModule.Conf
                .Set(MyConfigurationModule.TheFoo, GenericType<FooImpl>.Class)
                .Set(MyConfigurationModule.FooNess, "12")
                .Build();
            IFoo f = (IFoo)TangFactory.GetTang().NewInjector(c).GetInstance(fooType);
            Assert.Equal(f.getFooness(), 12);
            AvroConfigurationSerializer serializerCs = new AvroConfigurationSerializer();

            serializerCs.ToFileStream(c, "TangTestCs.avroconf");
            var c3 = serializerCs.FromFileStream("TangTestCs.avroconf");
            IFoo f3 = (IFoo)TangFactory.GetTang().NewInjector(c3).GetInstance(fooType);
            Assert.Equal(f3.getFooness(), 12);

            serializerCs.ToFile(c, "TangTestCs1.avro");
            var c4 = serializerCs.FromFile("TangTestCs1.avro");
            IFoo f4 = (IFoo)TangFactory.GetTang().NewInjector(c4).GetInstance(fooType);
            Assert.Equal(f4.getFooness(), 12);

            IConfigurationSerializer serializerImpl =
                (IConfigurationSerializer)
                    TangFactory.GetTang().NewInjector().GetInstance(typeof(IConfigurationSerializer));
            serializerImpl.ToFile(c, "TangTestCs1.avro");
            var c5 = serializerImpl.FromFile("TangTestCs1.avro");
            IFoo f5 = (IFoo)TangFactory.GetTang().NewInjector(c5).GetInstance(fooType);
            Assert.Equal(f5.getFooness(), 12);
        }

        [Fact]
        public void OmitOptionalTest()  
        {
            Type fooType = typeof(Org.Apache.REEF.Tang.Tests.Format.IFoo);

            IConfiguration c = MyConfigurationModule.Conf
                .Set(MyConfigurationModule.TheFoo, GenericType<FooImpl>.Class)
                .Build();
            IFoo f = (IFoo)TangFactory.GetTang().NewInjector(c).GetInstance(fooType);
            Assert.Equal(f.getFooness(), 42);
        }

        [Fact]
        public void OmitRequiredTest()
        {
            string msg = null;
            try 
            {
                MyConfigurationModule.Conf
                .Set(MyConfigurationModule.FooNess, "12")
                .Build();
                msg = "Attempt to build configuration before setting required option(s): { THE_FOO }";
            } 
            catch (Exception) 
            {
            }
            Assert.Null(msg);
        }

        [Fact]
        public void BadConfTest()
        {
            string msg = null;
            try
            {
                object obj = MyMissingBindConfigurationModule.BadConf;
                msg = "Found declared options that were not used in binds: { FOO_NESS }" + obj;
            }
            catch (Exception)
            {
            }
            Assert.Null(msg);
        }

        [Fact]
        public void NonExistentStringBindOK()
        {
            new MyBadConfigurationModule().BindImplementation(GenericType<IFoo>.Class, "i.do.not.exist");
        }

        [Fact]
        public void NonExistentStringBindNotOK()
        {
            string msg = null;
            try
            {
                new MyBadConfigurationModule().BindImplementation(GenericType<IFoo>.Class, "i.do.not.exist").Build();
                msg = "ConfigurationModule refers to unknown class: i.do.not.exist";
            }
            catch (Exception)
            {
            }
            Assert.Null(msg);            
        }

        [Fact]
        public void MultiBindTest() 
        {
            // Here we set some configuration values.  In true tang style,
            // you won't be able to set them more than once ConfigurationModule's
            // implementation is complete.
            IConfiguration c = MultiBindConfigurationModule.Conf
                .Set(MultiBindConfigurationModule.TheFoo, GenericType<FooImpl>.Class)
                .Set(MultiBindConfigurationModule.FOONESS, "12")
                .Build();
            IFoo f = (IFoo)TangFactory.GetTang().NewInjector(c).GetInstance(typeof(IFoo));
            IFoo g = (IFoo)TangFactory.GetTang().NewInjector(c).GetInstance(typeof(object));
            Assert.Equal(f.getFooness(), 12);
            Assert.Equal(g.getFooness(), 12);
            Assert.False(f == g);
          }

        [Fact]
        public void ForeignSetTest()
        {
            string msg = null;
            try
            {
                MultiBindConfigurationModule.Conf.Set(MyConfigurationModule.TheFoo, GenericType<FooImpl>.Class);
                msg = "Unknown Impl/Param when setting RequiredImpl.  Did you pass in a field from some other module?";
            }
            catch (Exception)
            {
            }
            Assert.Null(msg);
        }

        [Fact]
        public void ForeignBindTest()
        {
            string msg = null;
            try
            {
                new MyConfigurationModule().BindImplementation(GenericType<object>.Class, MultiBindConfigurationModule.TheFoo);
                msg = "Unknown Impl/Param when binding RequiredImpl.  Did you pass in a field from some other module?";
            }
            catch (Exception)
            {
            }
            Assert.Null(msg);
        }

        [Fact]
        public void SingletonTest() 
        {
            IConfiguration c = new MyConfigurationModule()
              .BindImplementation(GenericType<IFoo>.Class, MyConfigurationModule.TheFoo)
              .BindNamedParameter(GenericType<Fooness>.Class, MyConfigurationModule.FooNess)
              .Build()
              .Set(MyConfigurationModule.TheFoo, GenericType<FooImpl>.Class)
              .Build();
            IInjector i = TangFactory.GetTang().NewInjector(c);
            Assert.True(i.GetInstance(typeof(IFoo)) == i.GetInstance(typeof(IFoo)));
        }

        [Fact]
        public void ImmutablilityTest() 
        {
            // builder methods return copies; the original module is immutable
            ConfigurationModule builder1 = MyConfigurationModule.Conf
            .Set(MyConfigurationModule.TheFoo, GenericType<FooImpl>.Class);
   
            Assert.False(builder1 == MyConfigurationModule.Conf);

            IConfiguration config1 = builder1.Build();
  
            // reusable
            IConfiguration config2 = MyConfigurationModule.Conf
            .Set(MyConfigurationModule.TheFoo, GenericType<FooAltImpl>.Class)
            .Build();

            // instantiation of each just to be sure everything is fine in this situation
            IInjector i1 = TangFactory.GetTang().NewInjector(config1);
            IInjector i2 = TangFactory.GetTang().NewInjector(config2);
            Assert.Equal(42, ((IFoo)i1.GetInstance(typeof(IFoo))).getFooness());
            Assert.Equal(7, ((IFoo)i2.GetInstance(typeof(IFoo))).getFooness());
        }

        [Fact]
        public void SetParamTest() 
        {
            IConfiguration c = SetConfigurationModule.CONF
                .Set(SetConfigurationModule.P, "a")
                .Set(SetConfigurationModule.P, "b")
                .Build();
    
            ISet<string> s = (ISet<string>)TangFactory.GetTang().NewInjector(c).GetNamedInstance(typeof(SetName));
            Assert.Equal(s.Count, 2);
            Assert.True(s.Contains("a"));
            Assert.True(s.Contains("b"));
        }

        [Fact]
        public void SetClassTest() 
        {
            IConfiguration c = SetClassConfigurationModule.CONF
                .Set(SetClassConfigurationModule.P, GenericType<SubA>.Class)
                .Set(SetClassConfigurationModule.P, GenericType<SubB>.Class)
                .Build();
            ISet<ISuper> s = (ISet<ISuper>)TangFactory.GetTang().NewInjector(c).GetNamedInstance(typeof(SetClass));
            Assert.Equal(2, s.Count);
            
            bool sawA = false, sawB = false;    
            foreach (ISuper sup in s)
            {
                if (sup is SubA) 
                {
                    sawA = true;
                } 
                else if (sup is SubB) 
                {
                    sawB = true;
                } 
                else 
                {
                    Assert.True(false);
                }
            }
            Assert.True(sawA && sawB);
        }

        [Fact]
        public void SetClassRoundTripTest() 
        {
            IConfiguration c = SetClassConfigurationModule.CONF
                .Set(SetClassConfigurationModule.P, GenericType<SubA>.Class)
                .Set(SetClassConfigurationModule.P, GenericType<SubB>.Class)
                .Build();
            IConfigurationBuilder cb = TangFactory.GetTang().NewConfigurationBuilder(c);

            AvroConfigurationSerializer serializer = new AvroConfigurationSerializer();
            IConfiguration c2 = serializer.FromString(serializer.ToString(cb.Build()));

            // ConfigurationFile.AddConfiguration(cb, ConfigurationFile.ToConfigurationString(c));
            ISet<ISuper> s = (ISet<ISuper>)TangFactory.GetTang().NewInjector(c2).GetNamedInstance(typeof(SetClass));
            Assert.Equal(2, s.Count);
            bool sawA = false, sawB = false;
            foreach (ISuper sup in s)
            {
                if (sup is SubA)
                {
                    sawA = true;
                }
                else if (sup is SubB)
                {
                    sawB = true;
                }
                else
                {
                    Assert.True(false);
                }
            }
            Assert.True(sawA && sawB);
        }

        [Fact]
        public void ErrorOnStaticTimeSet()
        {
            string msg = null;
            try
            {
                StaticTimeSet.CONF.AssertStaticClean();
                msg =
                    " Detected statically set ConfigurationModule Parameter / Implementation.  set() should only be used dynamically.  Use bind...() instead.";
            }
            catch (ClassHierarchyException)
            {
            }
            Assert.Null(msg);
        }

         [Fact]
         public void ErrorOnSetMerge()
         {
             ConfigurationModuleBuilder cb = null;
             try
             {
                 ConfigurationModuleBuilder b = new ConfigurationModuleBuilder();
                 cb = b.Merge(StaticTimeSet.CONF);
             }
             catch (ClassHierarchyException e)
             {
                 System.Diagnostics.Debug.WriteLine(e);
             }
             Assert.Null(cb);
        }
    }

    [NamedParameter("Fooness", "Fooness", "42")]
    public class Fooness : Name<int>
    {        
    }

    public class FooImpl : IFoo
    {
        private readonly int fooness;

        [Inject]
        FooImpl([Parameter(typeof(Fooness))] int fooness) 
        { 
            this.fooness = fooness; 
        }

        public int getFooness()
        {
            return this.fooness;
        }
    }
    
    public class FooAltImpl : IFoo 
    {
        private readonly int fooness;
        
        [Inject]
        FooAltImpl([Parameter(Value = typeof(Fooness))] int fooness)
        {
            this.fooness = fooness;
        }
    
        public int getFooness() 
        {
            return 7;
        }
    }

    public sealed class MyConfigurationModule : ConfigurationModuleBuilder 
    {    
      // Tell us what implementation you want, or else!!    
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
      public static readonly RequiredImpl<IFoo> TheFoo = new RequiredImpl<IFoo>();

      // If you want, you can change the fooness.
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
      public static readonly OptionalParameter<int> FooNess = new OptionalParameter<int>();

      // This binds the above to tang configuration stuff.  You can use parameters more than
      // once, but you'd better use them all at least once, or I'll throw exceptions at you.
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
      public static readonly ConfigurationModule Conf = new MyConfigurationModule()
        .BindImplementation(GenericType<IFoo>.Class, MyConfigurationModule.TheFoo)
        .BindNamedParameter(GenericType<Fooness>.Class, MyConfigurationModule.FooNess)
        .Build();
    }

    public class MyMissingBindConfigurationModule : ConfigurationModuleBuilder 
    {    
      // Tell us what implementation you want, or else!!    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
        public static readonly RequiredImpl<IFoo> TheFoo = new RequiredImpl<IFoo>();
  
        // If you want, you can change the fooness.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
        public static readonly OptionalParameter<int> FooNess = new OptionalParameter<int>();
  
        // This conf doesn't use FOO_NESS.  Expect trouble below
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
        public static readonly ConfigurationModule BadConf = new MyMissingBindConfigurationModule()
            .BindImplementation(GenericType<IFoo>.Class, MyMissingBindConfigurationModule.TheFoo)
            .Build();
    }

    public class MyBadConfigurationModule : ConfigurationModuleBuilder 
    {    
    }

    public class MultiBindConfigurationModule : ConfigurationModuleBuilder 
    {    
        // Tell us what implementation you want, or else!!    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
        public static readonly RequiredImpl<IFoo> TheFoo = new RequiredImpl<IFoo>();

        // If you want, you can change the fooness.
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
        public static readonly OptionalParameter<int> FOONESS = new OptionalParameter<int>();

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Required by Tang")]
        public static readonly ConfigurationModule Conf = new MultiBindConfigurationModule()
          .BindImplementation(GenericType<IFoo>.Class, MultiBindConfigurationModule.TheFoo)
          .BindImplementation(GenericType<object>.Class, MultiBindConfigurationModule.TheFoo)
          .BindNamedParameter(GenericType<Fooness>.Class, MultiBindConfigurationModule.FOONESS)
          .Build();    
    }

    [NamedParameter]
    class SetName : Name<ISet<string>> 
    {
    }

    class SetConfigurationModule : ConfigurationModuleBuilder 
    {
        public static readonly RequiredParameter<string> P = new RequiredParameter<string>();

        public static readonly ConfigurationModule CONF = new SetConfigurationModule()
            .BindSetEntry(GenericType<SetName>.Class, SetConfigurationModule.P)
            .Build();
    }

    [NamedParameter]
    class SetClass : Name<ISet<ISuper>> 
    {
    }

    class SetClassConfigurationModule : ConfigurationModuleBuilder 
    {
        public static readonly RequiredParameter<ISuper> P = new RequiredParameter<ISuper>();
        public static readonly ConfigurationModule CONF = new SetClassConfigurationModule()
        .BindSetEntry(GenericType<SetClass>.Class, SetClassConfigurationModule.P)
        .Build();
    }

    class SubA : ISuper 
    {
        [Inject]
        public SubA() 
        {
        }
    }

    class SubB : ISuper 
    {
        [Inject]
        public SubB() 
        {
        }
    }
    
    class StaticTimeSet : ConfigurationModuleBuilder 
    {
        public static readonly OptionalImpl<ISuper> X = new OptionalImpl<ISuper>();
        public static readonly ConfigurationModule CONF = new StaticTimeSet()
            .BindImplementation(GenericType<ISuper>.Class, X)
            .Build()
            .Set(X, GenericType<SubA>.Class);
    }
}