// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.workspaceModel.storage.impl

import com.google.common.collect.HashBiMap
import com.intellij.workspaceModel.storage.WorkspaceEntity
import org.jetbrains.annotations.TestOnly
import java.util.concurrent.atomic.AtomicInteger

internal object ClassToIntConverter {
  private val class2Int = HashBiMap.create<Class<*>, Int>()
  private val idGenerator = AtomicInteger()

  @Synchronized
  fun getInt(clazz: Class<*>): Int = class2Int.getOrPut(clazz) { idGenerator.getAndIncrement() }

  @Synchronized
  fun getClassOrDie(id: Int): Class<*> = class2Int.inverse().getValue(id)

  fun getMap(): HashBiMap<Class<*>, Int> = class2Int

  fun fromMap(map: Map<Class<*>, Int>) {
    class2Int.clear()
    class2Int.putAll(map)
    idGenerator.set((map.map { it.value }.maxOrNull() ?: -1) + 1)
  }

  @TestOnly
  fun clear() {
    class2Int.clear()
    idGenerator.set(0)
  }
}

internal fun Class<*>.toClassId(): Int = ClassToIntConverter.getInt(this)
@Suppress("UNCHECKED_CAST")
internal inline fun <reified E> Int.findEntityClass(): Class<E> = ClassToIntConverter.getClassOrDie(this) as Class<E>
@Suppress("UNCHECKED_CAST")
internal fun Int.findWorkspaceEntity(): Class<WorkspaceEntity> = ClassToIntConverter.getClassOrDie(this) as Class<WorkspaceEntity>

