package ru.dbotthepony.mc.otm.core

import it.unimi.dsi.fastutil.ints.IntAVLTreeSet

class IDAllocator {
	private var highestID = 0
	private val gaps = IntAVLTreeSet()

	fun allocate(): Int {
		if (gaps.isEmpty()) {
			return highestID++
		} else {
			return gaps.removeFirst()
		}
	}

	fun release(id: Int) {
		if (id >= 0) {
			throw IllegalArgumentException("Invalid ID: $id")
		} else if (id >= highestID) {
			throw IllegalArgumentException("Not tracking ID: $id (highest known ID is ${highestID - 1})")
		} else if (id in gaps) {
			throw IllegalArgumentException("ID is already free: $id")
		}

		if (id + 1 == highestID) {
			highestID--
		} else {
			gaps.add(id)
		}
	}

	fun reset() {
		highestID = 0
		gaps.clear()
	}
}
