// Copyright 2008 Google Inc.
// Copyright (c) 2026 The elk-go Authors.
// Adapted to Go for elk-go in 2026.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

package javacompat

// GWTPriorityQueue reproduces GWT 2.11.0's java.util.PriorityQueue
// implementation linked into elkjs 0.12.0. The relevant GWT source is
// unchanged from the 2.9.0 runtime used by the former elkjs 0.8.2 baseline.
// Its bulk-add heapification and equal-item sift-down behavior differ
// observably from OpenJDK's PriorityQueue.
type GWTPriorityQueue[ any] struct {
	heap    []
	compare Comparator[]
}

func [ any]( Comparator[]) *GWTPriorityQueue[] {
	if  == nil {
		panic("javacompat.NewGWTPriorityQueue: nil comparator")
	}
	return &GWTPriorityQueue[]{compare: }
}

func ( *GWTPriorityQueue[]) () int      { return len(.heap) }
func ( *GWTPriorityQueue[]) () bool { return len(.heap) == 0 }

// AddAll appends the complete collection and then invokes GWT's recursive
// makeHeap routine. It does not repeatedly call Offer.
func ( *GWTPriorityQueue[]) ( []) bool {
	if len() == 0 {
		return false
	}
	.heap = append(.heap, ...)
	.makeHeap(0)
	return true
}

func ( *GWTPriorityQueue[]) ( ) { .Offer() }

func ( *GWTPriorityQueue[]) ( ) bool {
	 := len(.heap)
	.heap = append(.heap, )
	for  > 0 {
		 := 
		 = ( - 1) / 2
		if .compare(.heap[], ) <= 0 {
			.heap[] = 
			return true
		}
		.heap[] = .heap[]
	}
	.heap[] = 
	return true
}

func ( *GWTPriorityQueue[]) () (, bool) {
	if len(.heap) == 0 {
		var  
		return , false
	}
	return .heap[0], true
}

func ( *GWTPriorityQueue[]) () (, bool) {
	if len(.heap) == 0 {
		var  
		return , false
	}
	 := .heap[0]
	.removeAt(0)
	return , true
}

func ( *GWTPriorityQueue[]) ( int) {
	if *2+1 >= len(.heap) {
		return
	}
	.(*2 + 1)
	 := *2 + 2
	if  < len(.heap) {
		.()
	}
	.mergeHeaps()
}

func ( *GWTPriorityQueue[]) ( int) {
	 := len(.heap) - 1
	 := .heap[]
	var  
	.heap[] = 
	.heap = .heap[:]
	if  < len(.heap) {
		.heap[] = 
		.mergeHeaps()
	}
}

func ( *GWTPriorityQueue[]) ( int) {
	 := len(.heap)
	 := .heap[]
	for *2+1 <  {
		 := *2 + 1
		 :=  + 1
		 := 
		if  <  && .compare(.heap[], .heap[]) < 0 {
			 = 
		}
		// GWT uses a strict comparison here, so equal values move down.
		if .compare(, .heap[]) < 0 {
			break
		}
		.heap[] = .heap[]
		 = 
	}
	.heap[] = 
}