using NUnit.Framework;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StyletUnitTests
{
    [TestFixture]
    public class LabelledValueTests
    {
        [Test]
        public void StoresLabelAndValue()
        {
            var lbv = new LabelledValue<int>("an int", 5);
            Assert.AreEqual("an int", lbv.Label);
            Assert.AreEqual(5, lbv.Value);
        }

        [Test]
        public void SettingLabelAndValueRaisePropertyChangedNotifications()
        {
            var lbv = new LabelledValue<float>();

            lbv.PropertyChangedDispatcher = a => a();
            var changedProperties = new List<string>();
            lbv.PropertyChanged += (o, e) => changedProperties.Add(e.PropertyName);

            lbv.Label = "hello";
            lbv.Value = 2.2f;

            Assert.That(changedProperties, Is.EquivalentTo(new[] { "Label", "Value" }));
        }

        [Test]
        public void EqualsIdenticalLabelledValues()
        {
            var lbv1 = new LabelledValue<int>("int", 5);
            var lbv2 = new LabelledValue<int>("int", 5);

            // Test both variants
            Assert.That(lbv1.Equals(lbv2));
            Assert.That(lbv1.Equals((object)lbv2));
        }

        [Test]
        public void NotEqualLabeledValuesOfDifferentTypes()
        {
            var lbv1 = new LabelledValue<int>("test", 5);
            var lbv2 = new LabelledValue<double>("test", 5.0);

            Assert.False(lbv1.Equals(lbv2));
        }

        [Test]
        public void NotEqualNull()
        {
            var lbv = new LabelledValue<int>("test", 5);
            Assert.False(lbv.Equals(null));
        }

        [Test]
        public void NotEqualDifferentLabel()
        {
            var lbv1 = new LabelledValue<int>("test", 5);
            var lbv2 = new LabelledValue<int>("testy", 5);
            Assert.IsFalse(lbv1.Equals(lbv2));
        }

        [Test]
        public void NotEqualDifferentValues()
        {
            var lbv1 = new LabelledValue<int>("test", 5);
            var lbv2 = new LabelledValue<int>("test", 6);
            Assert.IsFalse(lbv1.Equals(lbv2));
        }

        [Test]
        public void GetHashCodeSameForIdenticalLabelledValues()
        {
            var lbv1 = new LabelledValue<int>("int", 5);
            var lbv2 = new LabelledValue<int>("int", 5);

            Assert.AreEqual(lbv1.GetHashCode(), lbv2.GetHashCode());
        }

        [Test]
        public void ToStringReturnsLabel()
        {
            var lbv = new LabelledValue<int>("label", 3);
            Assert.AreEqual("label", lbv.ToString());
        }

        [Test]
        public void CreateCreatesLabelledValue()
        {
            var lbv = LabelledValue.Create("test", 2.2f);
            Assert.AreEqual(new LabelledValue<float>("test", 2.2f), lbv);
        }
    }
}
