using qdr.fnd.core.pqueue.fnd.candidates;
using Quadarax.Foundation.Core.Data;

namespace qdr.fnd.core.pqueue.test.fnd.candidates
{
    internal class TypedArgumentExtTest
    {

        private TypedArgument[] _args;

        [SetUp]
        public void Setup()
        {
            _args = new TypedArgument[]
            {
                new TypedArgument("a", "1", typeof(int)),
                new TypedArgument("b", "2", typeof(int)),
                new TypedArgument("c", "3", typeof(int)),
                new TypedArgument("d", null, typeof(int)),
            };
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void GetArgumentValueOk()
        {
            var value = _args.GetArgumentValue<int>("a");
            Assert.That(value, Is.EqualTo(1));
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void GetArgumentValueFail()
        {
            Assert.Throws<ArgumentNullException>(()=>_args.GetArgumentValue<int>(null!));
            Assert.Throws<ArgumentNullException>(()=>_args.GetArgumentValue<int>(string.Empty));
            Assert.Throws<ArgumentOutOfRangeException>(()=>_args.GetArgumentValue<int>("x"));
            Assert.Throws<NotSupportedException>(()=>_args.GetArgumentValue<DateTime>("a"));
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void SetArgumentValueOk()
        {
            var value = 33;
            _args.SetArgumentValue<int>("a", value);
            Assert.That(value, Is.EqualTo(_args.First(x=>x.Name=="a").GetTypedValue<int>()));

            int? value2 = null;
            _args.SetArgumentValue<int?>("a", value2);
            Assert.That(_args.First(x=>x.Name=="a").GetTypedValue<int?>(), Is.Null);
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void SetArgumentValueFail()
        {
            Assert.Throws<ArgumentOutOfRangeException>(()=>_args.SetArgumentValue<int>("x", 0));
            Assert.Throws<ArgumentOutOfRangeException>(()=>_args.SetArgumentValue<DateTime>("a", DateTime.Now));
        }


        [Test(TestOf=typeof(TypedArgumentExt))]
        public void GetArgumentOk()
        {
            var arg = _args.GetArgument("a");
            Assert.That(arg.Name, Is.EqualTo(_args.First(x=>x.Name == "a").Name));
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void GetArgumentFail()
        {
            Assert.Throws<ArgumentNullException>(()=>_args.GetArgument(null!));
            Assert.Throws<ArgumentNullException>(()=>_args.GetArgument(string.Empty));
            Assert.Throws<ArgumentOutOfRangeException>(()=>_args.GetArgument("x"));
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void ContainsArgumentOk()
        {
            Assert.That(_args.ContainsArgument("a"), Is.True);
            Assert.That(_args.ContainsArgument("x"), Is.False);
        }

        [Test(TestOf=typeof(TypedArgumentExt))]
        public void ContainsArgumentFail()
        {
            Assert.Throws<ArgumentNullException>(()=>_args.ContainsArgument(null!));
            Assert.Throws<ArgumentNullException>(()=>_args.ContainsArgument(string.Empty));
        }
    }
}
