package ru.dbotthepony.mc.otm.core.collect

import ru.dbotthepony.mc.otm.core.stream
import java.util.concurrent.Future
import java.util.function.Supplier
import java.util.stream.Stream

class SupplierList<T> : AbstractList<T> {
	private val getters: Array<Supplier<T>>

	constructor(getters: Collection<Supplier<T>>) : super() {
		val iterator = getters.iterator()
		this.getters = Array(getters.size) { iterator.next() }
	}

	constructor(getters: Stream<Supplier<T>>) : super() {
		this.getters = getters.toArray { arrayOfNulls<Supplier<T>>(it) }
	}

	constructor(vararg getters: Supplier<T>) : super() {
		this.getters = Array(getters.size) { getters[it] }
	}

	constructor(size: Int, provider: (Int) -> Supplier<T>) {
		this.getters = Array(size, provider)
	}

	override val size: Int
		get() = getters.size

	override fun get(index: Int): T {
		return getters[index].get()
	}

	companion object {
		fun <T> ofLazy(vararg values: Lazy<T>): SupplierList<T> {
			return SupplierList(values.stream().map { Supplier { it.value } })
		}

		fun <T> ofFuture(vararg values: Future<T>): SupplierList<T> {
			return SupplierList(values.stream().map { Supplier { it.get() } })
		}
	}
}
