package pl.edu.pw.mini.sg.efgame

import java.util.UUID
import pl.edu.pw.mini.sg.game.deterministic.plugin.config.GameConfig


final case class EfGameConfig (
  gameTree: InnerGameNode,
  attackerIS : Map[Int, List[Int]],
  defenderIS : Map[Int, List[Int]],
  id: UUID
) extends GameConfig {
  //TODO weryfikacja poprawności
  val attackerIsNodes : Map[Int, Vector[InnerGameNode]] = {
    import scala.annotation.tailrec
    import scala.collection.mutable.{MultiMap => MMMap, HashMap => MMap, Set => MSet}
    val isnodes : MMMap[Int, InnerGameNode] = new MMap[Int, MSet[InnerGameNode]] with MMMap[Int, InnerGameNode]{}

    @tailrec def treeWalk(queue: List[InnerGameNode]) : Unit = {
      queue match {
        case Nil => ()
        case n :: ns => {
          isnodes.addBinding(n.attackerIS, n)
          treeWalk(n.successors.values.flatMap(x => x.values).collect{case x : InnerGameNode => x}.toList ++  ns)
        }
      }
    }
    treeWalk(List(gameTree))

    isnodes.toMap.mapValues(_.toVector)
  }

  val attackerContinuations : Map[(Int, Int), List[Int]] = {
    attackerIS.keys.flatMap(currentIs => attackerIS(currentIs).map(move => ((currentIs, move),
      attackerIsNodes(currentIs).flatMap(n => n.successors.values.map(_.apply(move)).map{x => x match {
        case InnerGameNode(_, attackerIS, _) => attackerIS
        case _ : LeafGameNode => -1
      }}).distinct.toList))).toMap
  }
}

sealed trait GameNode

final case class InnerGameNode(
  defenderIS: Int,
  attackerIS: Int,
  successors: Map[Int, Map[Int, GameNode]]

) extends GameNode


final case class LeafGameNode(
  defenderPayoff: Double,
  attackerPayoff: Double
) extends GameNode
