package pl.edu.pw.mini.sg.movingtargets.helpers

import argonaut.{ Json, JsonIdentity }
import canes.game.{ MethodInfo, MixedStrategyEntry, PureDefenderStrategy, Strategy, StrategyJson, TrainingResult, TrainingResultJson }
import pl.edu.pw.mini.jk.sg.game.common.DefenderMove
import pl.edu.pw.mini.sg.movingtargets.{ MovingTargetsGameConfig }

import scala.collection.JavaConverters._
import squants.time.Time

trait FactoryWithJsonOutput[DM <: DefenderMove] {
  def gameConfig : MovingTargetsGameConfig
  def convertPureStrategy(seq: java.util.List[DM]): PureDefenderStrategy

  final def toNativeStrategy(strategy: java.util.Map[_ <: java.util.List[DM], java.lang.Double]) : Strategy = 
  Strategy(gameConfig.id,
      strategy.asScala.map { case (seq, prob)  =>
        MixedStrategyEntry(prob, convertPureStrategy(seq))}.toVector
  )

  def defenderStrategyToJson(strategy: java.util.Map[_ <: java.util.List[DM], java.lang.Double]): argonaut.Json =
    JsonIdentity.ToJsonIdentity(toNativeStrategy(strategy)).asJson(StrategyJson.strategyCodec)

  def defenderResultAsJson(strategy: java.util.Map[_ <: java.util.List[DM], java.lang.Double], trainingTimeS: Double, methodName: String, methodConfig: Json, preprocessingTime: Time) : argonaut.Json =
    JsonIdentity.ToJsonIdentity(TrainingResult.calculatePayoffs(gameConfig.game, toNativeStrategy(strategy), trainingTimeS, MethodInfo(methodName, methodConfig), preprocessingTime.toSeconds))
      .asJson(TrainingResultJson.TrainingResultCodec)

}
