﻿/*
 * Licensed 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.
 */

namespace DotPulsar.Tests.Internal
{
    using DotPulsar.Internal;
    using FluentAssertions;
    using System.Buffers;
    using System.Linq;
    using Xunit;

    public class SequenceBuilderTests
    {
        [Fact]
        public void Append_GivenMultipleArrayInputs_ShouldArrangeInCorrectOrder()
        {
            //Arrange
            var a = new byte[] { 0x00, 0x01, 0x02, 0x03 };
            var b = new byte[] { 0x04, 0x05, 0x06, 0x07, 0x08 };
            var c = new byte[] { 0x09 };

            var builder = new SequenceBuilder<byte>().Append(a).Append(b).Append(c);

            //Act
            var actual = builder.Build().ToArray();

            //Assert
            var expected = CreateRange(0, 10);
            actual.Should().Equal(expected);
        }

        [Fact]
        public void Append_GivenMultipleArrayAndSequenceInputs_ShouldArrangeInCorrectOrder()
        {
            //Arrange
            var a = new byte[] { 0x00, 0x01 };
            var b = new byte[] { 0x02, 0x03 };
            var c = new byte[] { 0x04, 0x05 };
            var d = new byte[] { 0x06, 0x07 };
            var e = new byte[] { 0x08, 0x09 };

            var seq = new SequenceBuilder<byte>().Append(b).Append(c).Append(d).Build();
            var builder = new SequenceBuilder<byte>().Append(a).Append(seq).Append(e);

            //Act
            var actual = builder.Build().ToArray();

            //Assert
            var expected = CreateRange(0, 10);
            actual.Should().Equal(expected);
        }

        [Fact]
        public void Prepend_GivenMultipleArrayInputs_ShouldArrangeInCorrectOrder()
        {
            //Arrange
            var a = new byte[] { 0x00, 0x01, 0x02, 0x03 };
            var b = new byte[] { 0x04, 0x05, 0x06, 0x07, 0x08 };
            var c = new byte[] { 0x09 };

            var builder = new SequenceBuilder<byte>().Prepend(c).Prepend(b).Prepend(a);

            //Act
            var actual = builder.Build().ToArray();

            //Assert
            var expected = CreateRange(0, 10);
            actual.Should().Equal(expected);
        }

        [Fact]
        public void Prepend_GivenMultipleArrayAndSequenceInputs_ShouldArrangeInCorrectOrder()
        {
            //Arrange
            var a = new byte[] { 0x00, 0x01 };
            var b = new byte[] { 0x02, 0x03 };
            var c = new byte[] { 0x04, 0x05 };
            var d = new byte[] { 0x06, 0x07 };
            var e = new byte[] { 0x08, 0x09 };

            var seq = new SequenceBuilder<byte>().Prepend(d).Prepend(c).Prepend(b).Build();
            var builder = new SequenceBuilder<byte>().Prepend(e).Prepend(seq).Prepend(a);

            //Act
            var actual = builder.Build().ToArray();

            //Assert
            var expected = CreateRange(0, 10);
            actual.Should().Equal(expected);
        }

        [Fact]
        public void Build_GivenMultipleInvocations_ShouldCreateIdenticalSequences()
        {
            //Arrange
            var a = new byte[] { 0x00, 0x01 };
            var b = new byte[] { 0x02, 0x03 };

            var builder = new SequenceBuilder<byte>().Append(a).Append(b);

            //Act
            var actual1 = builder.Build().ToArray();
            var actual2 = builder.Build().ToArray();

            //Assert
            var expected = CreateRange(0, 4);
            actual1.Should().Equal(expected);
            actual2.Should().Equal(expected);
        }

        private static byte[] CreateRange(int start, int count)
        {
            var bytes = new byte[count];

            for (var i = 0; i < count; ++i)
                bytes[i] = System.Convert.ToByte(start + i);

            return bytes;
        }
    }
}
