package pl.edu.pw.mini.jk.sg.uct

import pl.edu.pw.mini.jk.lib.TraitJsonDecoder
import pl.edu.pw.mini.jk.sg.game.common.advanceable.{ AdvanceableState  }
import pl.edu.pw.mini.jk.sg.uct.statsupdater.{ StatsUpdaterFactory, StatsUpdaterFactoryJson }
import pl.edu.pw.mini.jk.sg.uct.tree.movehistory.LimitedHistoryTreeFactoryJson
import tree.UctTreeFactory
import scala.collection.JavaConverters._

import argonaut.DecodeJson
import pl.edu.pw.mini.jk.sg.game.common.SecurityGame
import pl.edu.pw.mini.jk.sg.uct.movehistory.{MoveHistoryFactoryJson, MoveHistoryFactory}
import stopcondition.{GameStopCondition, StopConditionDecodeJson}
import pl.edu.pw.mini.jk.sg.uct.tree.normal.NormalTreeFactoryJson


case class I2UctConfig[G <: SecurityGame] (stopConditions: List[GameStopCondition[G]],
  statsUpdaterFactory: StatsUpdaterFactory[AdvanceableState[_], Any],
selectionFormula: SelectionFunction, simulationsInLevel: Int, uctTreeFactory: UctTreeFactory) {

  def getStopConditions : java.util.List[_ <: GameStopCondition[_ >: G]] = stopConditions.asJava
  def getSelectionFormula = selectionFormula
  def getSimulationsInLevel = simulationsInLevel
}



object I2UctConfig {
  def decode[G <: SecurityGame](implicit scd: DecodeJson[GameStopCondition[G]],
    sud: DecodeJson[StatsUpdaterFactory[AdvanceableState[_], Any]],
    mhbfd: DecodeJson[MoveHistoryFactory],
    sfd: DecodeJson[SelectionFunction],
    utfd: DecodeJson[UctTreeFactory]
  ) = DecodeJson.jdecode5L(I2UctConfig.apply[G])("stopConditions", "statsUpdater", "selectionFormula", "simulationsInLevel", "uctTreeType")

  val decodeTreeFactory : DecodeJson[UctTreeFactory] = TraitJsonDecoder[UctTreeFactory](Map(
    "normalTree" -> NormalTreeFactoryJson.normalTreeFactoryDecode,
    "limitedHistory" -> LimitedHistoryTreeFactoryJson.decode
  )).decoder

  def defaultDecode : DecodeJson[I2UctConfig[SecurityGame]] = decode[SecurityGame](
    StopConditionDecodeJson.decoder,
    StatsUpdaterFactoryJson.decode,
    MoveHistoryFactoryJson.defaultDecode,
    DecodeSelectionFunctionJson.defaultDecode, decodeTreeFactory)
}




