-- Shuckle's held BERRY fermenting into BERRY JUICE:
-- ConvertBerriesToBerryJuice (engine/events/pokerus/pokerus.asm:124).
--
--   luajit tests/gen2_berry_juice_test.lua
--
-- ROM-free.  A 16/256 roll after every battle WIN, gated on
-- ENGINE_REACHED_GOLDENROD like the Pokerus roll it precedes; the first
-- party SHUCKLE holding a BERRY has its item rewritten, silently.  Shuckie
-- (the Cianwood loaner) arrives holding one, which is the payoff.

package.path = "./?.lua;./?/init.lua;" .. package.path

local S = require("tests.harness").suite("gen2 berry juice")
local check, eq = S.check, S.eq

local BerryJuice = require("src.battle.gen2.BerryJuice")

local function shuckle(item)
  return { species = "SHUCKLE", nickname = "SHUCKIE", item = item, hp = 20 }
end

-- ---- the roll and the walk ------------------------------------------------
do
  local party = { shuckle("BERRY") }
  eq(BerryJuice.convert(party, { reachedGoldenrod = true,
    random = function() return 15 end }), 1,
    "a roll under 16 converts")
  eq(party[1].item, "BERRY_JUICE", "the held BERRY became BERRY JUICE")

  party = { shuckle("BERRY") }
  eq(BerryJuice.convert(party, { reachedGoldenrod = true,
    random = function() return 16 end }), nil,
    "a roll at 16 does nothing")
  eq(party[1].item, "BERRY", "and the BERRY stays")

  party = { shuckle("BERRY") }
  eq(BerryJuice.convert(party, { reachedGoldenrod = false,
    random = function() return 0 end }), nil,
    "before Goldenrod the roll never runs")
end

-- ---- only the right mon, only the first -----------------------------------
do
  local party = {
    { species = "PIDGEY", item = "BERRY", hp = 20 },
    shuckle("GOLD_BERRY"),
    shuckle("BERRY"),
    shuckle("BERRY"),
  }
  eq(BerryJuice.convert(party, { reachedGoldenrod = true,
    random = function() return 0 end }), 3,
    "the walk finds the first SHUCKLE holding a plain BERRY")
  eq(party[1].item, "BERRY", "another species' BERRY is not touched")
  eq(party[2].item, "GOLD_BERRY", "a GOLD BERRY is not a BERRY")
  eq(party[3].item, "BERRY_JUICE", "the first match converts")
  eq(party[4].item, "BERRY",
    "and the routine returns there -- one conversion per win")
end

-- ---- the battle-exit call site --------------------------------------------
do
  -- convertAfterBattle mirrors Pokerus.giveAfterBattle: the flag comes off
  -- save.engineFlags[21].
  local save = { engineFlags = { [21] = true },
    party = { shuckle("BERRY") } }
  eq(BerryJuice.convertAfterBattle(save, nil,
    { random = function() return 0 end }), 1,
    "the save-facing wrapper reads ENGINE_REACHED_GOLDENROD")
  eq(save.party[1].item, "BERRY_JUICE", "and converts the save's party")

  save = { engineFlags = {}, party = { shuckle("BERRY") } }
  eq(BerryJuice.convertAfterBattle(save, nil,
    { random = function() return 0 end }), nil,
    "no flag, no ferment")

  -- The wire into the battle exit: GivePokerusAndConvertBerries runs the
  -- conversion FIRST, and BattleState:givePokerus is the port's copy of
  -- that arm.  A call site that is not spelled out in the file is not
  -- there at all (the same proof shape gen2_pokerus_test uses).
  local f = io.open("src/ui/gen2/BattleState.lua", "r")
  check(f ~= nil, "BattleState's source is readable")
  local body = f:read("*a")
  f:close()
  check(body:find("BerryJuice.convertAfterBattle(self.save, party)", 1, true)
    ~= nil, "givePokerus converts the berries")
  local convertAt = body:find("BerryJuice.convertAfterBattle(self.save, party)",
    1, true)
  local pokerusAt = body:find("Pokerus.giveAfterBattle(self.save, party)",
    1, true)
  check(convertAt and pokerusAt and convertAt < pokerusAt,
    "and does it before the Pokerus roll, the asm's own order")
end

S.finish()
