package de.nowchess.backcore.dto

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test

/** Exercises the Scala-generated synthetic methods (equals, hashCode, copy, productElement,
  * productElementName, toString, canEqual) on every DTO case class so that JaCoCo counts them as
  * covered.
  */
class DtoCoverageTest:

  @Test
  def playerInfoDtoSynthetics(): Unit =
    val a = PlayerInfoDto("id1", "Alice")
    val b = PlayerInfoDto("id1", "Alice")
    val c = PlayerInfoDto("id2", "Bob")
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("Alice"))
    assertTrue(a.canEqual(b))
    assertEquals("id1", a.productElement(0))
    assertEquals("Alice", a.productElement(1))
    assertEquals("id", a.productElementName(0))
    assertEquals("displayName", a.productElementName(1))
    assertEquals(a, a.copy())
    assertEquals(PlayerInfoDto("x", "Alice"), a.copy(id = "x"))
    assertEquals(PlayerInfoDto("id1", "X"), a.copy(displayName = "X"))

  @Test
  def okResponseSynthetics(): Unit =
    val a = OkResponse()
    val b = OkResponse()
    val c = OkResponse(ok = false)
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("true"))
    assertTrue(a.canEqual(b))
    assertEquals(true, a.productElement(0))
    assertEquals("ok", a.productElementName(0))
    assertEquals(a, a.copy())
    assertEquals(OkResponse(false), a.copy(ok = false))

  @Test
  def apiErrorResponseSynthetics(): Unit =
    val a = ApiErrorResponse("CODE", "msg")
    val b = ApiErrorResponse("CODE", "msg")
    val c = ApiErrorResponse("OTHER", "msg")
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("CODE"))
    assertTrue(a.canEqual(b))
    assertEquals("CODE", a.productElement(0))
    assertEquals("msg", a.productElement(1))
    assertEquals(None, a.productElement(2))
    assertEquals("code", a.productElementName(0))
    assertEquals("message", a.productElementName(1))
    assertEquals("field", a.productElementName(2))
    assertEquals(a, a.copy())
    assertEquals(ApiErrorResponse("X", "msg"), a.copy(code = "X"))
    assertEquals(ApiErrorResponse("CODE", "X"), a.copy(message = "X"))

  @Test
  def createGameRequestSynthetics(): Unit =
    val a = CreateGameRequest()
    val b = CreateGameRequest()
    val c = CreateGameRequest(white = Some(PlayerInfoDto("x", "X")))
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertNotNull(a.toString)
    assertTrue(a.canEqual(b))
    assertEquals(None, a.productElement(0))
    assertEquals(None, a.productElement(1))
    assertEquals("white", a.productElementName(0))
    assertEquals("black", a.productElementName(1))
    assertEquals(a, a.copy())
    assertEquals(CreateGameRequest(black = None), a.copy(black = None))

  @Test
  def importFenRequestSynthetics(): Unit =
    val a = ImportFenRequest(fen = "fen1")
    val b = ImportFenRequest(fen = "fen1")
    val c = ImportFenRequest(fen = "fen2")
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("fen1"))
    assertTrue(a.canEqual(b))
    assertEquals("fen1", a.productElement(0))
    assertEquals(None, a.productElement(1))
    assertEquals(None, a.productElement(2))
    assertEquals("fen", a.productElementName(0))
    assertEquals("white", a.productElementName(1))
    assertEquals("black", a.productElementName(2))
    assertEquals(a, a.copy())
    assertEquals(ImportFenRequest(fen = "x"), a.copy(fen = "x"))
    assertEquals(ImportFenRequest(fen = "fen1", white = None), a.copy(white = None))

  @Test
  def importPgnRequestSynthetics(): Unit =
    val a = ImportPgnRequest(pgn = "1. e4 *")
    val b = ImportPgnRequest(pgn = "1. e4 *")
    val c = ImportPgnRequest(pgn = "other")
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("e4"))
    assertTrue(a.canEqual(b))
    assertEquals("1. e4 *", a.productElement(0))
    assertEquals("pgn", a.productElementName(0))
    assertEquals(a, a.copy())
    assertEquals(ImportPgnRequest(pgn = "x"), a.copy(pgn = "x"))

  @Test
  def legalMoveDtoSynthetics(): Unit =
    val a = LegalMoveDto("e2", "e4", "e2e4", "normal")
    val b = LegalMoveDto("e2", "e4", "e2e4", "normal")
    val c = LegalMoveDto("d2", "d4", "d2d4", "normal")
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("e2"))
    assertTrue(a.canEqual(b))
    assertEquals("e2", a.productElement(0))
    assertEquals("e4", a.productElement(1))
    assertEquals("e2e4", a.productElement(2))
    assertEquals("normal", a.productElement(3))
    assertEquals(None, a.productElement(4))
    assertEquals("from", a.productElementName(0))
    assertEquals("to", a.productElementName(1))
    assertEquals("uci", a.productElementName(2))
    assertEquals("moveType", a.productElementName(3))
    assertEquals("promotion", a.productElementName(4))
    assertEquals(a, a.copy())
    assertEquals(LegalMoveDto("x", "e4", "xe4", "normal"), a.copy(from = "x", uci = "xe4"))
    assertEquals(LegalMoveDto("e2", "x", "e2x", "normal"), a.copy(to = "x", uci = "e2x"))

  @Test
  def legalMovesResponseSynthetics(): Unit =
    val a = LegalMovesResponse(List.empty)
    val b = LegalMovesResponse(List.empty)
    val c = LegalMovesResponse(List(LegalMoveDto("a1", "a2", "a1a2", "normal")))
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertNotNull(a.toString)
    assertTrue(a.canEqual(b))
    assertEquals(List.empty, a.productElement(0))
    assertEquals("moves", a.productElementName(0))
    assertEquals(a, a.copy())
    assertEquals(LegalMovesResponse(List.empty), a.copy(moves = List.empty))

  @Test
  def gameStateResponseSynthetics(): Unit =
    val a = GameStateResponse("fen", "pgn", "white", "started", None, List.empty, false, false)
    val b = GameStateResponse("fen", "pgn", "white", "started", None, List.empty, false, false)
    val c = GameStateResponse("fen2", "pgn", "white", "started", None, List.empty, false, false)
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("fen"))
    assertTrue(a.canEqual(b))
    assertEquals("fen", a.productElement(0))
    assertEquals("pgn", a.productElement(1))
    assertEquals("white", a.productElement(2))
    assertEquals("started", a.productElement(3))
    assertEquals(None, a.productElement(4))
    assertEquals(List.empty, a.productElement(5))
    assertEquals(false, a.productElement(6))
    assertEquals(false, a.productElement(7))
    assertEquals("fen", a.productElementName(0))
    assertEquals("pgn", a.productElementName(1))
    assertEquals("turn", a.productElementName(2))
    assertEquals("status", a.productElementName(3))
    assertEquals("winner", a.productElementName(4))
    assertEquals("moves", a.productElementName(5))
    assertEquals("undoAvailable", a.productElementName(6))
    assertEquals("redoAvailable", a.productElementName(7))
    assertEquals(a, a.copy())
    assertEquals(GameStateResponse("x", "pgn", "white", "started", None, List.empty, false, false), a.copy(fen = "x"))

  @Test
  def gameFullResponseSynthetics(): Unit =
    val p      = PlayerInfoDto("id", "Name")
    val state  = GameStateResponse("fen", "pgn", "white", "started", None, List.empty, false, false)
    val a      = GameFullResponse("gid", p, p, state)
    val b      = GameFullResponse("gid", p, p, state)
    val c      = GameFullResponse("other", p, p, state)
    assertEquals(a, b)
    assertNotEquals(a, c)
    assertFalse(a.equals(null))
    assertFalse(a.equals("other"))
    assertEquals(a.hashCode, b.hashCode)
    assertTrue(a.toString.contains("gid"))
    assertTrue(a.canEqual(b))
    assertEquals("gid", a.productElement(0))
    assertEquals(p, a.productElement(1))
    assertEquals(p, a.productElement(2))
    assertEquals(state, a.productElement(3))
    assertEquals("gameId", a.productElementName(0))
    assertEquals("white", a.productElementName(1))
    assertEquals("black", a.productElementName(2))
    assertEquals("state", a.productElementName(3))
    assertEquals(a, a.copy())
    assertEquals(GameFullResponse("x", p, p, state), a.copy(gameId = "x"))
