-- Driver: import a Stadium ROM through the OPTIONS row, with the modal file
-- dialog stubbed out.
--
-- Everything except the dialog itself is the real path: the row is built the
-- way the OPTIONS menu builds it, its step() is pressed, StadiumRomPick reads
-- the file with io.open (love.filesystem cannot see an absolute path),
-- StadiumInstall builds from those bytes, and the loading screen goes up over
-- whatever asked. A modal dialog cannot be driven, so choose() is replaced
-- with the answer a player would have given it.
return function(game)
  local U = dofile("tests/drivers/util.lua")
  local DIR = os.getenv("SHOT_DIR") or ".scratchpad"
  local lib = game.mods.exports.DRAMATIC_SHAPE.lib
  local Pick = lib.require("StadiumRomPick")
  local Install = lib.require("StadiumInstall")
  local Pack = lib.require("StadiumPack")
  local Battles = lib.require("OverworldBattle")

  U.teleport(game, "ROUTE_1", 5, 8, "down")
  U.wait(30)

  -- FIRST let the automatic first-run build finish. A ROM is sitting in
  -- baseroms/ in this checkout, so StadiumScreen.maybePush has already pushed
  -- a loading screen and started one -- and import() refuses to start a
  -- second while that runs, so every step below would silently no-op against
  -- it. maybePush asks ONCE per boot, so once this is drained it stays
  -- drained and the purge below cannot be undone behind our backs.
  local drain = 0
  while (Install.pending() or Install.status.state == "building")
        and drain < 5400 do
    U.wait(10); drain = drain + 10
  end
  while game.stack:top() and game.stack:top() ~= game.overworld do
    U.wait(10)
  end
  U.log(("drained the automatic first-run build in %d frames"):format(drain))

  -- back to a machine that has never built them, whatever earlier runs left
  for _, name in ipairs(love.filesystem.getDirectoryItems(Pack.CACHE_DIR)) do
    love.filesystem.remove(Pack.CACHE_DIR .. "/" .. name)
  end
  Install.forget()
  Pack.forget()

  local function settle(what)
    local waited = 0
    while Install.status.state == "building" and waited < 5400 do
      U.wait(10)
      waited = waited + 10
    end
    U.log(("%s: %d frames (%.1fs) -- state=%s error=%s")
          :format(what, waited, waited / 60, tostring(Install.status.state),
                  tostring(Install.status.error)))
    return waited
  end

  U.log(("picker available on this platform: %s"):format(
        tostring(Pick.available())))
  U.log(("BEFORE: models available = %s, 3D-BTL offers %d rungs")
        :format(tostring(Install.available()), Battles.setting:rungs()))

  local row = Pick.row()
  if not row then U.log("no import row on this platform") return end
  U.log(("row reads: %s = %s"):format(row.label, row.value()))

  -- ------- the wrong file first, because a refusal must not leave a mess
  U.log("-- picking a file that is not a Stadium ROM --")
  Pick.choose = function() return "/not/a/real/path.z64" end
  local realRead = Pick.read
  Pick.read = function() return ("\x80\x37\x12\x40"):rep(4096) end
  row.step(game)
  settle("wrong file")
  U.shot(game, ("%s/import_1_refused.png"):format(DIR))
  U.log(("  still not installed: %s, row still reads %s")
        :format(tostring(not Install.available()), row.value()))
  U.wait(300)   -- let the failure notice time out and pop itself

  -- ------- and now the real one
  U.log("-- picking the real ROM --")
  Pick.read = realRead
  local abs = love.filesystem.getWorkingDirectory() .. "/baseroms/baserom.z64"
  local picked = false
  Pick.choose = function() picked = true return abs end
  Install.status.state = "idle"
  row.step(game)
  U.log(("  choose() called: %s, state = %s, loading screen on top: %s")
        :format(tostring(picked), tostring(Install.status.state),
                tostring(game.stack:top() ~= game.overworld)))
  U.wait(30)
  U.shot(game, ("%s/import_2_building.png"):format(DIR))
  settle("real ROM")
  U.wait(120)

  U.log(("AFTER: models available = %s, 3D-BTL offers %d rungs, row reads %s")
        :format(tostring(Install.available()), Battles.setting:rungs(),
                row.value()))
  Battles.setting:setValue("stadium", game)
  U.log(("  and 3D-BTL can now be set to STADIUM A: %s")
        :format(tostring(Battles.setting:get() == "stadium")))
  -- and the ROM was NOT copied anywhere: the only baserom physfs can see is
  -- the one in the game folder this checkout already had, never a copy in
  -- the save directory (which is where a mod's writes land)
  local where = love.filesystem.getRealDirectory("baseroms/baserom.z64")
  U.log(("  the only ROM on the read path is the game folder's own: %s (%s)")
        :format(tostring(where == love.filesystem.getWorkingDirectory()),
                tostring(where)))
  U.log(("  the save directory has no baseroms folder: %s")
        :format(tostring(love.filesystem.getInfo(
                  love.filesystem.getSaveDirectory() .. "/baseroms") == nil)))

  -- ------- and the wrong file, now that a GOOD set is installed
  --
  -- The serious case. The marker is the only thing that makes 151 files on
  -- disk count as installed, so a refusal that writes one anyway would
  -- UNINSTALL a working set -- and the player would have pressed a row called
  -- STADIUM ROM, picked the wrong file, and lost the models they already had.
  U.log("-- picking the wrong file again, with models already installed --")
  Pick.read = function() return ("7@"):rep(4096) end
  Install.status.state = "idle"
  row.step(game)
  settle("wrong file over a good install")
  U.wait(300)
  Install.forget()
  Pack.forget()
  U.log(("  the good install SURVIVED: %s, row reads %s, 3D-BTL offers %d rungs")
        :format(tostring(Install.available()), row.value(),
                Battles.setting:rungs()))
  U.log(("  and a real model still loads: %s")
        :format(tostring(Pack.load(25) ~= nil)))
  U.log("done -- " .. DIR)
end
