package pl.edu.pw.mini.sg.se

import argonaut.{CursorHistory, Json}
import pl.edu.pw.mini.sg.game.boundedrationality.DistortedPayoff
import pl.edu.pw.mini.sg.game.deterministic.plugin.GameParams
import pl.edu.pw.mini.sg.game.deterministic.{AdvanceablePlayerVisibleState, DeterministicGame, PlayerVisibleState}
import pl.edu.pw.mini.sg.mixed.{UctAttackerSampler, UctAttackerSamplerConfig}
import pl.edu.pw.mini.sg.mixed.json.MixedMethodConfigJson
import pl.edu.pw.mini.sg.mixed.tree.MixedStrategyNode
import pl.edu.pw.mini.sg.results.{MethodInfo, NewMixedMethodInfo}
import pl.edu.pw.mini.sg.rng.RandomGenerator
import scalaz.{NonEmptyList, Validation}
import squants.Time
import squants.time.Nanoseconds


final class UctAttackerSamplerMethod(
  uasConfig: UctAttackerSamplerConfig
) extends StrategyMethod {
  def findBehavioralStrategy[
    DM, AM,
    DS <: PlayerVisibleState[DM],
    AS <: AdvanceablePlayerVisibleState[AM, AS],
    G <: DeterministicGame[DM, AM, DS, AS, G]
  ](
    game: G, params: GameParams, rng: RandomGenerator
  ) : (MixedStrategyNode[DM, DS, Unit], DistortedPayoff, Time) = {
    val (strategy, payoff) = UctAttackerSampler.findBehavioralStrategy[DM, AM, DS, AS, G](game, params, rng, uasConfig)
    (strategy, payoff, Nanoseconds(0))
  }



  override def getMethodInfo(configFileName: String, gitHash: String, version: String): MethodInfo = {
    NewMixedMethodInfo(configFileName, gitHash, version)
  }
}

object UctAttackerSamplerMethod extends StrategyMethodParser[UctAttackerSamplerMethod] {
  def tryParse(config: Json) : Validation[NonEmptyList[(String, CursorHistory)], UctAttackerSamplerMethod] =
    Validation.fromEither(config.as(MixedMethodConfigJson.defaultUctSamplerCodec).toEither).map(new UctAttackerSamplerMethod(_)).toValidationNel

  override val name = "UCT"
}

