﻿/*
 * 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.Internal.Extensions;

using System;
using System.Buffers;

public static class ReadOnlySequenceExtensions
{
    public static bool StartsWith<T>(this ReadOnlySequence<T> sequence, ReadOnlyMemory<T> target) where T : IEquatable<T>
    {
        if (target.Length > sequence.Length)
            return false;

        var targetIndex = 0;
        var targetSpan = target.Span;

        foreach (var memory in sequence)
        {
            var span = memory.Span;

            for (var i = 0; i < span.Length; ++i)
            {
                if (!span[i].Equals(targetSpan[targetIndex]))
                    return false;

                ++targetIndex;

                if (targetIndex == targetSpan.Length)
                    return true;
            }
        }

        return false;
    }

    public static uint ReadUInt32(this ReadOnlySequence<byte> sequence, long start, bool isBigEndian)
    {
        if (sequence.Length < 4 + start)
            throw new ArgumentOutOfRangeException(nameof(start), start, "Sequence must be at least 4 bytes long from 'start' to end");

        var reverse = isBigEndian != BitConverter.IsLittleEndian;
        var union = new UIntUnion();
        var read = 0;

        foreach (var memory in sequence)
        {
            if (start > memory.Length)
            {
                start -= memory.Length;
                continue;
            }

            var span = memory.Span;

            for (var i = (int) start; i < span.Length; ++i, ++read)
            {
                switch (read)
                {
                    case 0:
                        if (reverse) union.B0 = span[i];
                        else union.B3 = span[i];
                        continue;
                    case 1:
                        if (reverse) union.B1 = span[i];
                        else union.B2 = span[i];
                        continue;
                    case 2:
                        if (reverse) union.B2 = span[i];
                        else union.B1 = span[i];
                        continue;
                    case 3:
                        if (reverse) union.B3 = span[i];
                        else union.B0 = span[i];
                        break;
                }
            }

            if (read == 4)
                break;

            start = 0;
        }

        return union.UInt;
    }
}
