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

import java.util.UUID

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

class SearchGameConfigSpec extends WordSpec with Matchers {

  "SearchGameConfig" should {

    val config = SearchGameConfig(
      GraphConfig(7, List(Edge(5, 1), Edge(5, 2), Edge(6, 1),Edge(6, 2), Edge(6, 3), Edge(1, 1), Edge(2, 2), Edge(3, 3) ,Edge(0, 1), 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(5, 6), List(SearchGameTarget(4, 1.0)), List(List(1, 2, 5), List(1, 2, 3, 6)), List(1,2,3), coveringUpTracksPossible = true,
      UUID.fromString("658f740c-8c22-473f-8d6f-5cbea8c10f3d"))

    val noSlowMoveConfig = config.copy(coveringUpTracksPossible = false)
    val graphConfig = config.graphConfig.edges.groupBy(_.from).map{case (v, connected) => (v, connected.map(_.to))}.withDefaultValue(Vector())

    "provide a list with possible moves for each defender and position" which {
      "has length equal to number of defenders" in {
        val possibleDefenderMoves = config.possibleDefenderMoves
        possibleDefenderMoves should have length 2
      }

      "has correct vertices for all defenders and positions" in {
        val possibleDefenderMoves = config.possibleDefenderMoves
        val firstDefenderMoves = possibleDefenderMoves.head
        val secondDefenderMoves = possibleDefenderMoves(1)

        firstDefenderMoves.keys should  contain theSameElementsAs List(1, 2, 5)
        firstDefenderMoves(1) should contain theSameElementsAs List(1, 2)
        firstDefenderMoves(2) should contain theSameElementsAs List(1, 2)
        firstDefenderMoves(5) should contain theSameElementsAs List(1, 2)

        secondDefenderMoves.keys should  contain theSameElementsAs List(1, 2, 3, 6)
        secondDefenderMoves(1) should contain theSameElementsAs List(1, 2)
        secondDefenderMoves(2) should contain theSameElementsAs List(1, 2, 3)
        secondDefenderMoves(3) should contain theSameElementsAs List(3)
        secondDefenderMoves(6) should contain theSameElementsAs List(1, 2, 3)

      }
    }
    "provide a list with possible moves for the attacker for each position" which {
      "has length equal to vertex count" in {
        val attackerMoves = config.possibleAttackerMoves
        attackerMoves should have length 7
      }


      "does include covering up tracks if it is possible" in {
        val attackerMoves = config.possibleAttackerMoves
        val stayVertices = Range(0, config.graphConfig.vertexCount).filter(v => config.graphConfig.edges.contains(Edge(v,v)))
        forAll(stayVertices) {
          v => attackerMoves(v) should contain theSameElementsAs
            graphConfig(v).map(SearchGameAttackerMove(_))
        }
      }

    }
  }
}
