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

import canes.game.{ Depot, Target, MovingTargetsGame }
import java.util.UUID
import org.scalatest._
import pl.edu.pw.mini.sg.movingtargets.{ MovingTargetsGameConfig }
import scala.collection.immutable.SortedSet

import scala.collection.JavaConverters._

class CoverageDefenderStateCachedSpec extends WordSpec with Matchers {
    val gameConfig = MovingTargetsGameConfig(MovingTargetsGame(
    UUID.fromString("123e4567-e89b-12d3-a456-426655440000"),
    List(Depot(1, 5, 5), Depot(2, 8, 8)),
    List(Target(1, 1, 2, List(3, 33, 50), 10, -5, -8, 4)),
    0.5, 2, 2, List(1, 1), 1, 2, 1, 0
  ), 1)

  "CoverageDefender initial state wit simple game" when {

    val (initial, _) = CoverageDefenderStateCached.generateStateTree(gameConfig)

    "not advanced" should {

      "cover target 1" in {
        initial.coveredTargets should equal(Set(1))
      }

      "allow moves to empty and full coverage" in {
        initial.getPossibleMoves.asScala should equal(List(
          CoverageDefenderMove(SortedSet()), CoverageDefenderMove(SortedSet(1))
        ))
      }
    }

    val nextNocov = initial.advance(CoverageDefenderMove(SortedSet()))
    "advancedByEmptyCoverage" should {
      "not cover any targets" in {
        nextNocov.coveredTargets should equal(Set())
      }

      "allow both moves" in {
        nextNocov.getPossibleMoves.asScala should equal(List(
          CoverageDefenderMove(SortedSet()), CoverageDefenderMove(SortedSet(1))
        ))
      }

      "have value 1 of timestep" in {
        nextNocov.timeStep should equal(1)
      }

    }

    val twiceNocov = nextNocov.advance(CoverageDefenderMove(SortedSet()))
    "advanced  twice by empty coverage" should {
      "have timestep 2" in {
        twiceNocov.timeStep should equal(2)
      }

      "not cover any targets" in {
        twiceNocov.coveredTargets should equal(Set())
      }
    }


    val nextCov = initial.advance(CoverageDefenderMove(SortedSet(1)))
    "advanced by single coverage" should {
      "have timestep 1" in {
        nextCov.timeStep should equal(1)
      }
    }
  }

  "CoverageDefenderState with low speed game" when {
    val gameConfig = MovingTargetsGameConfig(MovingTargetsGame(
      UUID.fromString("123e4567-e89b-12d3-a456-426655440000"),
      List(Depot(1, 5, 5), Depot(2, 8, 8)),
      List(Target(1, 1, 2, List(3, 33, 50), 10, -5, -8, 4)),
      0.5, 2, 1, List(1, 1), 1, 2, 1, 0
    ), 1)

    val (init, _) = CoverageDefenderStateCached.generateStateTree(gameConfig)

    "not advanced" should {
      "allow only coverage move" in {
        init.getPossibleMoves.asScala should contain only(CoverageDefenderMove(SortedSet(1)))
      }

      "throw an exception when playing nocover move" in {
        an[IllegalArgumentException] should be thrownBy(init.advance(CoverageDefenderMove(SortedSet())))
      }
    }

    "advanced with cover move" should {
      val next = init.advance(CoverageDefenderMove(SortedSet(1)))

      "allow two moves" in {
        next.getPossibleMoves.asScala should contain only(CoverageDefenderMove(SortedSet()), CoverageDefenderMove(SortedSet(1)))
      }
    }

  }
}
