package pl.edu.pw.mini.sg.bosansky

import argonaut.Parse
import org.scalatest.{Matchers, WordSpec}
import pl.edu.pw.mini.sg.game.graph.sud.{DeterministicSingleUnitMoveGraphGame, SingleUnitAttackerState, SingleUnitDefenderState}
import pl.edu.pw.mini.sg.game.graph.{DeterministicGraphGameConfig, DeterministicGraphGameConfigJson}

import scala.io.Source

class SingleUnitDeterministicGameUtilsProviderSpec extends WordSpec with Matchers {


 "A DeterministicGameUtils for the SingleUnitDeterministicGame" should {
   val utils = new DeterministicGameUtilsProvider[Int, Int, SingleUnitDefenderState, SingleUnitAttackerState, DeterministicSingleUnitMoveGraphGame]
   import DeterministicGraphGameConfigJson.deterministicGraphGameConfigCodec
   val fileSource = Source.fromInputStream(getClass.getResourceAsStream("game3a-5.ggame"))
   val gameConfig = Parse.decode[DeterministicGraphGameConfig](fileSource.mkString) match {
     case Right(c) => c
   }
   fileSource.close()
    val game = DeterministicSingleUnitMoveGraphGame(gameConfig)

    "provide a getAllSequences method" which {
      "returns initial state as first element" in {
        val (state, _, _) = utils.getAllSequences(game).head
        state should equal(game)
      }

      "returns empty move lists in first element" in {
        val (_, defenderMoves, attackerMoves) = utils.getAllSequences(game).head
        defenderMoves.isEmpty should be(true)
        attackerMoves.isEmpty should be(true)
      }

      "returns sequences with equal length attackerMoves and defenderMoves" in {
        val lengths = utils.getAllSequences(game).map(s => s._2.length == s._3.length)
        lengths.forall(v => v) should be(true)
      }

      "returns sequences with moveLists no longer than game length" in {
        val maxLengths = utils.getAllSequences(game).map(_._2.length).max
        maxLengths should equal(gameConfig.rounds)
      }

      "for game 3a 5" should {
        "return 50971 unique sequences" in {
          val seqCount = utils.getAllSequences(game).distinct.length
          seqCount should equal(50971)
        }
      }

      "for small building 96 5" should {
        val fileSource = Source.fromInputStream(getClass.getResourceAsStream("smallbuilding-96-5.ggame"))
        val gameConfig = Parse.decode[DeterministicGraphGameConfig](fileSource.mkString) match {
          case Right(c) => c
        }
        fileSource.close()
        val game = DeterministicSingleUnitMoveGraphGame(gameConfig)
        "return 54001 unique sequences" in {
          val seqCount = utils.getAllSequences(game).distinct.length
          seqCount should equal(54001)
        }
      }

    }
 }
}
