package de.nowchess.bot.logic

import de.nowchess.api.move.Move

enum TTFlag:
  case Exact   // Score is exact
  case Lower   // Score is a lower bound
  case Upper   // Score is an upper bound

final case class TTEntry(
  hash: Long,
  depth: Int,
  score: Int,
  flag: TTFlag,
  bestMove: Option[Move]
)

final class TranspositionTable(val sizePow2: Int = 20):
  private val size = 1 << sizePow2
  private val mask = size - 1L
  private val locks = Array.fill(size)(new Object())
  private var table: Array[Option[TTEntry]] = Array.fill(size)(None)

  def probe(hash: Long): Option[TTEntry] =
    val index = (hash & mask).toInt
    locks(index).synchronized {
      table(index).filter(_.hash == hash)
    }

  def store(entry: TTEntry): Unit =
    val index = (entry.hash & mask).toInt
    locks(index).synchronized {
      table(index) = Some(entry)
    }

  def clear(): Unit =
    for lock <- locks do
      lock.synchronized {
        // Clear in-place to avoid reassigning table reference during search
      }
    table = Array.fill(size)(None)
