public ClaimResult CanClaimGame(ClaimGameDomainRequest request, Instant?nextBidTime, int?validDropSlot, bool acquiringNow, bool drafting)
    {
        var currentDate = _clock.GetToday();
        var dateOfPotentialAcquisition = currentDate;

        if (nextBidTime.HasValue)
        {
            dateOfPotentialAcquisition = nextBidTime.Value.ToEasternDate();
        }

        var leagueYear = request.LeagueYear;

        List <ClaimError> claimErrors = new List <ClaimError>();

        var basicErrors = GetBasicErrors(leagueYear.League, request.Publisher);

        claimErrors.AddRange(basicErrors);

        if (request.MasterGame is not null)
        {
            var masterGameErrors = GetGenericSlotMasterGameErrors(leagueYear, request.MasterGame, leagueYear.Year, false, currentDate,
                                                                  dateOfPotentialAcquisition, request.CounterPick, request.CounterPickedGameIsManualWillNotRelease, drafting);
            claimErrors.AddRange(masterGameErrors);
        }

        LeaguePublisherGameSet gameSet = new LeaguePublisherGameSet(request.Publisher.PublisherID, leagueYear.Publishers);
        bool thisPlayerAlreadyHas      = gameSet.ThisPlayerStandardGames.ContainsGame(request);
        bool gameAlreadyClaimed        = gameSet.OtherPlayerStandardGames.ContainsGame(request);

        if (!request.CounterPick)
        {
            if (gameAlreadyClaimed)
            {
                claimErrors.Add(new ClaimError("Cannot claim a game that someone already has.", false));
            }

            if (thisPlayerAlreadyHas)
            {
                claimErrors.Add(new ClaimError("Cannot claim a game that you already have.", false));
            }
        }

        if (request.CounterPick)
        {
            bool otherPlayerHasCounterPick = gameSet.OtherPlayerCounterPicks.ContainsGame(request);
            if (otherPlayerHasCounterPick)
            {
                claimErrors.Add(new ClaimError("Cannot counter-pick a game that someone else has already counter picked.", false));
            }
            bool thisPlayerHasCounterPick = gameSet.ThisPlayerCounterPicks.ContainsGame(request);
            if (thisPlayerHasCounterPick)
            {
                claimErrors.Add(new ClaimError("You already have that counter pick.", false));
            }

            bool otherPlayerHasDraftGame = gameSet.OtherPlayerStandardGames.ContainsGame(request);
            if (!otherPlayerHasDraftGame)
            {
                claimErrors.Add(new ClaimError("Cannot counter pick a game that no other player is publishing.", false));
            }
        }

        MasterGameWithEligibilityFactors?eligibilityFactors = null;

        if (request.MasterGame is not null)
        {
            eligibilityFactors = leagueYear.GetEligibilityFactorsForMasterGame(request.MasterGame, dateOfPotentialAcquisition);
        }

        var slotResult = SlotEligibilityService.GetPublisherSlotAcquisitionResult(request.Publisher, leagueYear.Options, eligibilityFactors, request.CounterPick, validDropSlot, acquiringNow);

        if (!slotResult.SlotNumber.HasValue)
        {
            claimErrors.AddRange(slotResult.ClaimErrors);
            return(new ClaimResult(claimErrors, null));
        }

        var result = new ClaimResult(claimErrors, slotResult.SlotNumber.Value);

        if (result.Overridable && request.ManagerOverride)
        {
            return(new ClaimResult(slotResult.SlotNumber.Value));
        }

        return(result);
    }
    public ClaimResult CanAssociateGame(AssociateGameDomainRequest request)
    {
        List <ClaimError> associationErrors = new List <ClaimError>();
        var basicErrors = GetBasicErrors(request.LeagueYear.League, request.Publisher);

        associationErrors.AddRange(basicErrors);
        var leagueYear = request.LeagueYear;

        var currentDate = _clock.GetToday();
        var dateOfPotentialAcquisition = currentDate;

        IReadOnlyList <ClaimError> masterGameErrors = GetGenericSlotMasterGameErrors(leagueYear, request.MasterGame, leagueYear.Year, false, currentDate,
                                                                                     dateOfPotentialAcquisition, request.PublisherGame.CounterPick, false, false);

        associationErrors.AddRange(masterGameErrors);

        LeaguePublisherGameSet gameSet = new LeaguePublisherGameSet(request.Publisher.PublisherID, request.LeagueYear.Publishers);

        bool thisPlayerAlreadyHas = gameSet.ThisPlayerStandardGames.ContainsGame(request.MasterGame);
        bool gameAlreadyClaimed   = gameSet.OtherPlayerStandardGames.ContainsGame(request.MasterGame);

        if (!request.PublisherGame.CounterPick)
        {
            if (gameAlreadyClaimed)
            {
                associationErrors.Add(new ClaimError("Cannot claim a game that someone already has.", false));
            }

            if (thisPlayerAlreadyHas)
            {
                associationErrors.Add(new ClaimError("Cannot claim a game that you already have.", false));
            }
        }

        if (request.PublisherGame.CounterPick)
        {
            bool otherPlayerHasCounterPick = gameSet.OtherPlayerCounterPicks.ContainsGame(request.MasterGame);
            if (otherPlayerHasCounterPick)
            {
                associationErrors.Add(new ClaimError("Cannot counter-pick a game that someone else has already counter picked.", false));
            }
            bool thisPlayerHasCounterPick = gameSet.ThisPlayerCounterPicks.ContainsGame(request.MasterGame);
            if (thisPlayerHasCounterPick)
            {
                associationErrors.Add(new ClaimError("You already have that counter pick.", false));
            }

            bool otherPlayerHasDraftGame = gameSet.OtherPlayerStandardGames.ContainsGame(request.MasterGame);
            if (!otherPlayerHasDraftGame)
            {
                associationErrors.Add(new ClaimError("Cannot counter pick a game that no other player is publishing.", false));
            }
        }

        var result = new ClaimResult(associationErrors, request.PublisherGame.SlotNumber);

        if (result.Overridable && request.ManagerOverride)
        {
            return(new ClaimResult(request.PublisherGame.SlotNumber));
        }

        return(result);
    }