package ru.dbotthepony.kstarbound.defs.util

import com.github.benmanes.caffeine.cache.Interner
import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap

/**
 * Возвращает глубокую, неизменяемую копию [input] примитивов/List'ов/Map'ов
 */
fun enrollList(input: List<Any>, interner: Interner<String> = Interner { it }): ImmutableList<Any> {
	val builder = ImmutableList.builder<Any>()

	for (v in input) {
		when (v) {
			is Map<*, *> -> builder.add(enrollMap(v as Map<String, Any>, interner))
			is List<*> -> builder.add(enrollList(v as List<Any>, interner))
			else -> builder.add((v as? String)?.let(interner::intern) ?: v)
		}
	}

	return builder.build()
}

/**
 * Возвращает глубокую, неизменяемую копию [input] примитивов/List'ов/Map'ов
 */
fun enrollMap(input: Map<String, Any>, interner: Interner<String> = Interner { it }): ImmutableMap<String, Any> {
	val builder = ImmutableMap.builder<String, Any>()

	for ((k, v) in input) {
		when (v) {
			is Map<*, *> -> builder.put(interner.intern(k), enrollMap(v as Map<String, Any>, interner))
			is List<*> -> builder.put(interner.intern(k), enrollList(v as List<Any>, interner))
			else -> builder.put(interner.intern(k), (v as? String)?.let(interner::intern) ?: v)
		}
	}

	return builder.build()
}
