﻿/*
 * 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;
    using System.Buffers;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;
    using Xunit;

    public class ChunkingPipelineTests
    {
        [Fact]
        public async Task Send_GivenSequenceIsUnderChunkSize_ShouldWriteArrayOnce()
        {
            //Arrange
            var a = new byte[] { 0x00, 0x01, 0x02, 0x03 };
            var b = new byte[] { 0x04, 0x05, 0x06, 0x07 };
            var sequence = new SequenceBuilder<byte>().Append(a).Append(b).Build();
            var mockStream = new MockStream();
            var sut = new ChunkingPipeline(mockStream, 9);

            //Act
            await sut.Send(sequence);

            //Assert
            var expected = sequence.ToArray();
            var actual = mockStream.GetReadOnlySequence();
            actual.ToArray().Should().Equal(expected);
            actual.IsSingleSegment.Should().BeTrue();
        }

        [Theory]
        [InlineData(4, 6, 3, 4, 6, 3)]     // No segments can be merged
        [InlineData(1, 6, 4, 7, 4, null)]  // Can merge a and b
        [InlineData(4, 6, 1, 4, 7, null)]  // Can merge b and c
        public async Task Send_GivenSequenceIsOverChunkSize_ShouldWriteMultipleArrays(int length1, int length2, int length3, int expected1, int expected2, int? expected3)
        {
            //Arrange
            var a = Enumerable.Range(0, length1).Select(i => (byte) i).ToArray();
            var b = Enumerable.Range(length1, length2).Select(i => (byte) i).ToArray();
            var c = Enumerable.Range(length1 + length2, length3).Select(i => (byte) i).ToArray();
            var sequence = new SequenceBuilder<byte>().Append(a).Append(b).Append(c).Build();
            var mockStream = new MockStream();
            var sut = new ChunkingPipeline(mockStream, 8);

            //Act
            await sut.Send(sequence);

            //Assert
            var expected = sequence.ToArray();
            var actual = mockStream.GetReadOnlySequence();
            actual.ToArray().Should().Equal(expected);
            GetNumberOfSegments(actual).Should().Be(expected3.HasValue ? 3 : 2);

            var segmentNumber = 0;
            foreach (var segment in actual)
            {
                switch (segmentNumber)
                {
                    case 0:
                        segment.Length.Should().Be(expected1);
                        break;
                    case 1:
                        segment.Length.Should().Be(expected2);
                        break;
                    case 2:
                        expected3.Should().NotBeNull();
                        segment.Length.Should().Be(expected3);
                        break;
                }
                ++segmentNumber;
            }
        }

        private static int GetNumberOfSegments(ReadOnlySequence<byte> sequence)
        {
            var numberOfSegments = 0;
            var enumerator = sequence.GetEnumerator();
            while (enumerator.MoveNext())
                ++numberOfSegments;
            return numberOfSegments;
        }

        private class MockStream : Stream
        {
            private readonly SequenceBuilder<byte> _builder;

            public MockStream() => _builder = new SequenceBuilder<byte>();
            public override bool CanRead => throw new NotImplementedException();
            public override bool CanSeek => throw new NotImplementedException();
            public override bool CanWrite => true;
            public override long Length => throw new NotImplementedException();
            public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
            public override void Flush() => throw new NotImplementedException();
            public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException();
            public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();
            public override void SetLength(long value) => throw new NotImplementedException();
            public override void Write(byte[] buffer, int offset, int count) => _builder.Append(new ReadOnlyMemory<byte>(buffer, offset, count));
            public ReadOnlySequence<byte> GetReadOnlySequence() => _builder.Build();
        }
    }
}
