package de.nowchess.backcore.resource

import io.quarkus.test.junit.QuarkusTest
import io.restassured.RestAssured
import org.hamcrest.Matchers.{containsString, equalTo}
import org.junit.jupiter.api.Test

@QuarkusTest
class UndoRedoTest:

  private val initialFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"

  private def createGame(): String =
    RestAssured
      .`given`()
      .contentType("application/json")
      .body("{}")
      .when()
      .post("/api/board/game")
      .`then`()
      .statusCode(201)
      .extract()
      .path[String]("gameId")

  @Test
  def undoAfterMoveRestoresOriginalPosition(): Unit =
    val gameId = createGame()
    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/move/e2e4")
      .`then`()
      .statusCode(200)

    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/undo")
      .`then`()
      .statusCode(200)
      .body("fen", equalTo(initialFen))
      .body("undoAvailable", equalTo(false))

  @Test
  def redoAfterUndoRestoresMovedPosition(): Unit =
    val gameId = createGame()
    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/move/e2e4")
      .`then`()
      .statusCode(200)

    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/undo")
      .`then`()
      .statusCode(200)

    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/redo")
      .`then`()
      .statusCode(200)
      .body("fen", containsString("4P3"))
      .body("turn", equalTo("black"))

  @Test
  def undoWithNoHistoryReturns400(): Unit =
    val gameId = createGame()
    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/undo")
      .`then`()
      .statusCode(400)

  @Test
  def redoWithNoRedoStackReturns400(): Unit =
    val gameId = createGame()
    RestAssured
      .`given`()
      .when()
      .post(s"/api/board/game/$gameId/redo")
      .`then`()
      .statusCode(400)

  @Test
  def undoMoveOnUnknownGameReturns404(): Unit =
    RestAssured
      .`given`()
      .when()
      .post("/api/board/game/XXXXXXXX/undo")
      .`then`()
      .statusCode(404)

  @Test
  def redoMoveOnUnknownGameReturns404(): Unit =
    RestAssured
      .`given`()
      .when()
      .post("/api/board/game/XXXXXXXX/redo")
      .`then`()
      .statusCode(404)
