package pl.edu.pw.mini.sg.mixed.expansion

import argonaut.{ CodecJson, DecodeJson, EncodeJson }
import pl.edu.pw.mini.sg.game.deterministic.TreeExpander
import pl.edu.pw.mini.sg.game.deterministic.single.GameWithPayoff
import pl.edu.pw.mini.sg.json.{ FlatTraitJsonCodec, TraitSubtypeCodec }
import pl.edu.pw.mini.sg.mcts.MctsParameters


object ExpansionJson {
  implicit def randomExpansionCodec(implicit
    expanderEncode: EncodeJson[TreeExpander[Any, Any, GameWithPayoff]],
    expanderDecode: DecodeJson[TreeExpander[Any, Any, GameWithPayoff]]
  ) : CodecJson[RandomNodeExpansion] = CodecJson.casecodec6(RandomNodeExpansion.apply, RandomNodeExpansion.unapply)("subtreeExpandedMultiplier", "probabilityBoost", "positiveExpander", "negativeExpander", "initialExpander", "expandWorsePayoff")

  implicit def mctsExpansionCodec(implicit
    mctsParamsEncode: EncodeJson[MctsParameters],
    mctsParamsDecode: DecodeJson[MctsParameters]
  ): CodecJson[MctsNodeExpansion]  =
    CodecJson.casecodec3(
      MctsNodeExpansion.apply, MctsNodeExpansion.unapply
    )(
      "mctsParams", "expandWorsePayoff", "expansionProbability"
    )


  implicit def expansionCodec(implicit
    expanderEncode: EncodeJson[TreeExpander[Any, Any, GameWithPayoff]],
    expanderDecode: DecodeJson[TreeExpander[Any, Any, GameWithPayoff]],
    mctsParamsEncode: EncodeJson[MctsParameters],
    mctsParamsDecode: DecodeJson[MctsParameters]
  ) : FlatTraitJsonCodec[NodeExpansionDecision] =
    new FlatTraitJsonCodec[NodeExpansionDecision](List(
      TraitSubtypeCodec(randomExpansionCodec, randomExpansionCodec, "random"),
      TraitSubtypeCodec(mctsExpansionCodec, mctsExpansionCodec, "mcts")
    ))
}
