package pl.edu.pw.mini.game.search

import java.util.UUID

import org.scalatest.{Matchers, WordSpec}
import pl.edu.pw.mini.sg.game.graph.{Edge, GraphConfig}

class SearchGameAttackerStateSpec extends WordSpec with Matchers {
  val config = SearchGameConfig(
    GraphConfig(5, List(Edge(0, 1), Edge(1, 1), Edge(2, 2), Edge(3, 3), Edge(0, 2), Edge(0, 3), Edge(1, 2), Edge(2, 1), Edge(2, 3), Edge(1, 4), Edge(2, 4), Edge(3, 4)).toVector),
    5, 2, 0, Vector(1, 2), List(SearchGameTarget(4, 1.0)), List(List(1, 2), List(1, 2, 3)), List(1,2,3), coveringUpTracksPossible = true,
    UUID.fromString("658f740c-8c22-473f-8d6f-5cbea8c10f3d"))

  "The SearchGameAttackerStateSpec class" should {
    val finishedState = config.attackerInitialState.copy(timeStep = 5)

    "provide a possibleMoves method" which {
      "returns empty list when game is over" in {
        val moves = finishedState.possibleMoves
        moves should be (empty)
      }

      "returns unchanged moves from config otherwise" in {
        val state = SearchGameAttackerState(config, 1, 2)

        val moves = state.possibleMoves
        moves should contain theSameElementsAs List(
          SearchGameAttackerMove(1),
          SearchGameAttackerMove(2),
          SearchGameAttackerMove(4)
        )

      }
    }

    "define an equals method" which {
      val state = SearchGameAttackerState(config, 0, 2)
      "returns true for states with the same positions, timesteps" in {
        val result = state.equals(SearchGameAttackerState(config, 0, 2))
        result should be (true)
      }

      "returns false for comparision between different types" in {
        val result = state.equals(4)
        result should be (false)
      }

      "returns false for states with different positions" in {
        val result = state.equals(SearchGameAttackerState(config, 2, 2))
        result should be (false)
      }

      "returns false for states with different timesteps" in {
        val result = state.equals(SearchGameAttackerState(config, 0, 3))
        result should be (false)
      }
    }

    "define a possibleContinuation method" which {
      val state = SearchGameAttackerState(config, 1, 2)
      "returns one element list" in {
        val newStates = state.possibleContinuations(SearchGameAttackerMove(2))
        newStates should have length 1

      }
      "returns correct new state for normal move" in {
        val newState = state.possibleContinuations(SearchGameAttackerMove(2)).head
        newState should equal(SearchGameAttackerState(config, 2, 3))
      }

      "returns state with the same position when covering up tracks" in {
        val newState = state.possibleContinuations(SearchGameAttackerMove(1)).head
        newState should equal(SearchGameAttackerState(config, 1, 3))
      }
    }
  }

}
