local ____lualib = require("lualib_bundle")
local Set = ____lualib.Set
local __TS__New = ____lualib.__TS__New
local __TS__ArraySome = ____lualib.__TS__ArraySome
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
local ____exports = {}
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
local Challenge = ____isaac_2Dtypescript_2Ddefinitions.Challenge
local SeedEffect = ____isaac_2Dtypescript_2Ddefinitions.SeedEffect
local ____cachedEnumValues = require("arrays.cachedEnumValues")
local SEED_EFFECTS = ____cachedEnumValues.SEED_EFFECTS
local ____cachedClasses = require("core.cachedClasses")
local game = ____cachedClasses.game
local ____constantsFirstLast = require("core.constantsFirstLast")
local FIRST_CHARACTER = ____constantsFirstLast.FIRST_CHARACTER
local ____characters = require("functions.characters")
local getCharacterName = ____characters.getCharacterName
local ____log = require("functions.log")
local log = ____log.log
local ____types = require("functions.types")
local isString = ____types.isString
--- Helper function to see if any seed effects (i.e. Easter Eggs) are enabled for the current run.
-- 
-- @param exceptions Optional. An array of seed effects to ignore.
function ____exports.anySeedEffectEnabled(self, exceptions)
    local seeds = game:GetSeeds()
    if exceptions == nil then
        local numSeedEffects = seeds:CountSeedEffects()
        return numSeedEffects > 0
    end
    local exceptionsSet = __TS__New(Set, exceptions)
    return __TS__ArraySome(
        SEED_EFFECTS,
        function(____, seedEffect) return seeds:HasSeedEffect(seedEffect) and not exceptionsSet:has(seedEffect) end
    )
end
--- Alias for the `anySeedEffectEnabled` function.
function ____exports.anyEasterEggEnabled(self, exceptions)
    return ____exports.anySeedEffectEnabled(nil, exceptions)
end
--- Helper function to get the seed effects (i.e. Easter Eggs) that are enabled for the current run.
function ____exports.getSeedEffects(self)
    local seeds = game:GetSeeds()
    return __TS__ArrayFilter(
        SEED_EFFECTS,
        function(____, seedEffect) return seedEffect ~= SeedEffect.NORMAL and seeds:HasSeedEffect(seedEffect) end
    )
end
--- Helper function to check whether the player is playing on a set seed (i.e. that they entered in a
-- specific seed by pressing tab on the character selection screen). When the player resets the game
-- on a set seed, the game will not switch to a different seed.
-- 
-- Under the hood, this checks if the current challenge is `Challenge.NULL` and the
-- `Seeds.IsCustomRun` method.
function ____exports.onSetSeed(self)
    local seeds = game:GetSeeds()
    local customRun = seeds:IsCustomRun()
    local challenge = Isaac.GetChallenge()
    return challenge == Challenge.NULL and customRun
end
--- Helper function to check whether the player is on a Victory Lap (i.e. they answered "yes" to the
-- popup that happens after defeating The Lamb).
function ____exports.onVictoryLap(self)
    local numVictoryLaps = game:GetVictoryLap()
    return numVictoryLaps > 0
end
--- Helper function to restart the run using the console command of "restart". If the player is
-- playing a seeded run, then it will restart the game to the beginning of the seed. Otherwise, it
-- will put the player on a run with an entirely new seed.
-- 
-- You can optionally specify a `PlayerType` to restart the game as that character.
function ____exports.restart(self, character)
    if character == nil then
        local command = "restart"
        log("Restarting the run with a console command of: " .. command)
        Isaac.ExecuteCommand(command)
        return
    end
    if character < FIRST_CHARACTER then
        error(("Restarting as a character of " .. tostring(character)) .. " would crash the game.")
    end
    local command = "restart " .. tostring(character)
    local characterName = getCharacterName(nil, character)
    log((((("Restarting the run as " .. characterName) .. " (") .. tostring(character)) .. ") with a console command of: ") .. command)
    Isaac.ExecuteCommand(command)
end
--- Helper function to restart the run on a particular starting seed.
-- 
-- Under the hood, this function executes the `seed` console command.
-- 
-- @param startSeedOrStartSeedString Either the numerical start seed (e.g. 268365970) or the start
-- seed string (e.g. "AAJ2 8V9C").
function ____exports.setRunSeed(self, startSeedOrStartSeedString)
    local startSeedString = isString(nil, startSeedOrStartSeedString) and startSeedOrStartSeedString or Seeds.Seed2String(startSeedOrStartSeedString)
    local command = "seed " .. startSeedString
    log("Restarting the run to set a seed with a console command of: " .. command)
    Isaac.ExecuteCommand(command)
end
--- Helper function to change the run status to that of an unseeded run with a new random seed.
-- 
-- This is useful to revert the behavior where playing on a set seed and restarting the game will
-- not take you to a new seed.
-- 
-- Under the hood, this function calls the `Seeds.Reset` method and the
-- `Seeds.Restart(Challenge.NULL)` method.
function ____exports.setUnseeded(self)
    local seeds = game:GetSeeds()
    seeds:Reset()
    seeds:Restart(Challenge.NULL)
end
return ____exports
