// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package maps

import (
	"internal/abi"
	"unsafe"
)

type CtrlGroup = ctrlGroup

const DebugLog = debugLog

var AlignUpPow2 = alignUpPow2

const MaxTableCapacity = maxTableCapacity
const MaxAvgGroupLoad = maxAvgGroupLoad

// This isn't equivalent to runtime.maxAlloc. It is fine for basic testing but
// we can't properly test hint alloc overflows with this.
const maxAllocTest = 1 << 30

func newTestMapType[K comparable, V any]() *abi.MapType {
	var m map[K]V
	mTyp := abi.TypeOf(m)
	mt := (*abi.MapType)(unsafe.Pointer(mTyp))
	return mt
}

func NewTestMap[K comparable, V any](hint uintptr) (*Map, *abi.MapType) {
	mt := newTestMapType[K, V]()
	return NewMap(mt, hint, nil, maxAllocTest), mt
}

func (m *Map) TableCount() int {
	if m.dirLen <= 0 {
		return 0
	}
	return m.dirLen
}

// Total group count, summed across all tables.
func (m *Map) GroupCount() uint64 {
	if m.dirLen <= 0 {
		if m.dirPtr == nil {
			return 0
		}
		return 1
	}

	var n uint64
	var lastTab *table
	for i := range m.dirLen {
		t := m.directoryAt(uintptr(i))
		if t == lastTab {
			continue
		}
		lastTab = t
		n += t.groups.lengthMask + 1
	}
	return n
}

// Return a key from a group containing no empty slots.
//
// Returns nil if there are no full groups.
// Returns nil if a group is full but contains entirely deleted slots.
// Returns nil if the map is small.
func (m *Map) KeyFromFullGroup(typ *abi.MapType) unsafe.Pointer {
	if m.dirLen <= 0 {
		return nil
	}

	var lastTab *table
	for i := range m.dirLen {
		t := m.directoryAt(uintptr(i))
		if t == lastTab {
			continue
		}
		lastTab = t

		for i := uint64(0); i <= t.groups.lengthMask; i++ {
			g := t.groups.group(typ, i)
			match := g.ctrls().matchEmpty()
			if match != 0 {
				continue
			}

			// All full or deleted slots.
			for j := uintptr(0); j < abi.MapGroupSlots; j++ {
				if g.ctrls().get(j) == ctrlDeleted {
					continue
				}
				slotKey := g.key(typ, j)
				if typ.IndirectKey() {
					slotKey = *((*unsafe.Pointer)(slotKey))
				}
				return slotKey
			}
		}
	}

	return nil
}

// Returns nil if the map is small.
func (m *Map) TableFor(typ *abi.MapType, key unsafe.Pointer) *table {
	if m.dirLen <= 0 {
		return nil
	}

	hash := typ.Hasher(key, m.seed)
	idx := m.directoryIndex(hash)
	return m.directoryAt(idx)
}

func (t *table) GrowthLeft() uint64 {
	return uint64(t.growthLeft)
}

// Returns the start address of the groups array.
func (t *table) GroupsStart() unsafe.Pointer {
	return t.groups.data
}

// Returns the length of the groups array.
func (t *table) GroupsLength() uintptr {
	return uintptr(t.groups.lengthMask + 1)
}
