// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

package sctp

import (
	
)

// pendingBaseQueue

type pendingBaseQueue struct {
	queue []*chunkPayloadData
}

func newPendingBaseQueue() *pendingBaseQueue {
	return &pendingBaseQueue{queue: []*chunkPayloadData{}}
}

func ( *pendingBaseQueue) ( *chunkPayloadData) {
	.queue = append(.queue, )
}

func ( *pendingBaseQueue) () *chunkPayloadData {
	if len(.queue) == 0 {
		return nil
	}
	 := .queue[0]
	.queue = .queue[1:]

	return 
}

func ( *pendingBaseQueue) ( int) *chunkPayloadData {
	if len(.queue) == 0 ||  < 0 ||  >= len(.queue) {
		return nil
	}

	return .queue[]
}

func ( *pendingBaseQueue) () int {
	return len(.queue)
}

// pendingQueue

type pendingQueue struct {
	unorderedQueue      *pendingBaseQueue
	orderedQueue        *pendingBaseQueue
	nBytes              int
	selected            bool
	unorderedIsSelected bool
}

// Pending queue errors.
var (
	ErrUnexpectedChuckPoppedUnordered = errors.New("unexpected chunk popped (unordered)")
	ErrUnexpectedChuckPoppedOrdered   = errors.New("unexpected chunk popped (ordered)")
	ErrUnexpectedQState               = errors.New("unexpected q state (should've been selected)")
)

func newPendingQueue() *pendingQueue {
	return &pendingQueue{
		unorderedQueue: newPendingBaseQueue(),
		orderedQueue:   newPendingBaseQueue(),
	}
}

func ( *pendingQueue) ( *chunkPayloadData) {
	if .unordered {
		.unorderedQueue.push()
	} else {
		.orderedQueue.push()
	}
	.nBytes += len(.userData)
}

func ( *pendingQueue) () *chunkPayloadData {
	if .selected {
		if .unorderedIsSelected {
			return .unorderedQueue.get(0)
		}

		return .orderedQueue.get(0)
	}

	if  := .unorderedQueue.get(0);  != nil {
		return 
	}

	return .orderedQueue.get(0)
}

func ( *pendingQueue) ( *chunkPayloadData) error { //nolint:cyclop
	if .selected { //nolint:nestif
		var  *chunkPayloadData
		if .unorderedIsSelected {
			 = .unorderedQueue.pop()
			if  !=  {
				return ErrUnexpectedChuckPoppedUnordered
			}
		} else {
			 = .orderedQueue.pop()
			if  !=  {
				return ErrUnexpectedChuckPoppedOrdered
			}
		}
		if .endingFragment {
			.selected = false
		}
	} else {
		if !.beginningFragment {
			return ErrUnexpectedQState
		}
		if .unordered {
			 := .unorderedQueue.pop()
			if  !=  {
				return ErrUnexpectedChuckPoppedUnordered
			}
			if !.endingFragment {
				.selected = true
				.unorderedIsSelected = true
			}
		} else {
			 := .orderedQueue.pop()
			if  !=  {
				return ErrUnexpectedChuckPoppedOrdered
			}
			if !.endingFragment {
				.selected = true
				.unorderedIsSelected = false
			}
		}
	}
	.nBytes -= len(.userData)

	return nil
}

func ( *pendingQueue) () int {
	return .nBytes
}

func ( *pendingQueue) () int {
	return .unorderedQueue.size() + .orderedQueue.size()
}