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

using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;

public sealed class SequenceBuilder<T> where T : notnull
{
    private readonly LinkedList<ReadOnlyMemory<T>> _elements;

    public SequenceBuilder()
        => _elements = new LinkedList<ReadOnlyMemory<T>>();

    public SequenceBuilder<T> Prepend(ReadOnlyMemory<T> memory)
    {
        _elements.AddFirst(memory);
        return this;
    }

    public SequenceBuilder<T> Prepend(ReadOnlySequence<T> sequence)
    {
        LinkedListNode<ReadOnlyMemory<T>>? index = null;

        foreach (var memory in sequence)
        {
            index = index is null
                ? _elements.AddFirst(memory)
                : _elements.AddAfter(index, memory);
        }

        return this;
    }

    public SequenceBuilder<T> Append(ReadOnlyMemory<T> memory)
    {
        _elements.AddLast(memory);
        return this;
    }

    public SequenceBuilder<T> Append(ReadOnlySequence<T> sequence)
    {
        foreach (var memory in sequence)
            _elements.AddLast(memory);

        return this;
    }

    public long Length => _elements.Sum(e => e.Length);

    public ReadOnlySequence<T> Build()
    {
        var node = _elements.First;
        if (node is null)
            return ReadOnlySequence<T>.Empty;

        var current = new Segment(node.Value);
        var start = current;

        while (true)
        {
            node = node.Next;
            if (node is null)
                break;

            current = current.CreateNext(node.Value);
        }

        return new ReadOnlySequence<T>(start, 0, current, current.Memory.Length);
    }

    private sealed class Segment : ReadOnlySequenceSegment<T>
    {
        public Segment(ReadOnlyMemory<T> memory, long runningIndex = 0)
        {
            Memory = memory;
            RunningIndex = runningIndex;
        }

        public Segment CreateNext(ReadOnlyMemory<T> memory)
        {
            var segment = new Segment(memory, RunningIndex + Memory.Length);
            Next = segment;
            return segment;
        }
    }
}
