private async Task <IHttpActionResult> Handle(RegisterMatchMessage message)
        {
            WebsiteConfig websiteConfig = DocumentSession.Load <WebsiteConfig>(WebsiteConfig.GlobalId);

            Player[] players =
                DocumentSession.Query <Player, PlayerSearch>()
                .ToArray()
                .Where(x => x.PlayerItem?.LicNbr != null)
                .ToArray();
            Roster pendingMatch = DocumentSession.Load <Roster>(message.RosterId);

            try
            {
                var             parser          = new BitsParser(players);
                BitsMatchResult bitsMatchResult = await bitsClient.GetBitsMatchResult(pendingMatch.BitsMatchId);

                if (bitsMatchResult.HeadInfo.MatchFinished == false)
                {
                    Log.Info($"Match {pendingMatch.BitsMatchId} not yet finished");
                    return(Ok());
                }

                if (pendingMatch.IsFourPlayer)
                {
                    Parse4Result parse4Result = parser.Parse4(bitsMatchResult, websiteConfig.ClubId);
                    if (parse4Result != null)
                    {
                        List <string> allPlayerIds = GetPlayerIds(parse4Result);
                        pendingMatch.SetPlayers(allPlayerIds);
                        ExecuteCommand(new RegisterMatch4Command(pendingMatch, parse4Result));
                    }
                }
                else
                {
                    ParseResult parseResult = parser.Parse(bitsMatchResult, websiteConfig.ClubId);
                    if (parseResult != null)
                    {
                        List <string> allPlayerIds = GetPlayerIds(parseResult);
                        pendingMatch.SetPlayers(allPlayerIds);
                        ExecuteCommand(new RegisterMatchCommand(pendingMatch, parseResult));
                    }
                }
            }
            catch (Exception e)
            {
                ErrorSignal
                .FromCurrentContext()
                .Raise(new Exception($"Unable to auto register match {pendingMatch.Id} ({pendingMatch.BitsMatchId})", e));
                Log.Warn(e);
                return(Ok(e.ToString()));
            }

            return(Ok());
        }
        private static List <string> GetPlayerIds(Parse4Result parse4Result)
        {
            IEnumerable <string> query = from game in parse4Result.Series.First().Games
                                         select game.Player;

            string[]             playerIds = query.ToArray();
            var                  playerIdsWithoutReserve = new HashSet <string>(playerIds);
            IEnumerable <string> restQuery = from serie in parse4Result.Series
                                             from game in serie.Games
                                             where playerIdsWithoutReserve.Contains(game.Player) == false
                                             select game.Player;
            var allPlayerIds = playerIds.Concat(
                new HashSet <string>(restQuery).Where(x => playerIdsWithoutReserve.Contains(x) == false)).ToList();

            return(allPlayerIds);
        }
 public record Command(
     string RosterId,
     Parse4Result Result,
     string?SummaryText,
     string?SummaryHtml);
        private async Task <IHttpActionResult> Handle(VerifyMatchMessage message)
        {
            Roster roster = DocumentSession.Load <Roster>(message.RosterId);

            if (roster.IsVerified && message.Force == false)
            {
                return(Ok());
            }
            WebsiteConfig websiteConfig = DocumentSession.Load <WebsiteConfig>(WebsiteConfig.GlobalId);
            HeadInfo      result        = await bitsClient.GetHeadInfo(roster.BitsMatchId);

            ParseHeaderResult header = BitsParser.ParseHeader(result, websiteConfig.ClubId);

            // chance to update roster values
            var update = new Roster.Update(
                Roster.ChangeType.VerifyMatchMessage,
                "system")
            {
                OilPattern = header.OilPattern,
                Date       = header.Date,
                Opponent   = header.Opponent,
                Location   = header.Location
            };

            if (roster.MatchResultId != null)
            {
                // update match result values
                BitsMatchResult bitsMatchResult = await bitsClient.GetBitsMatchResult(roster.BitsMatchId);

                Player[] players = DocumentSession.Query <Player, PlayerSearch>()
                                   .ToArray()
                                   .Where(x => x.PlayerItem?.LicNbr != null)
                                   .ToArray();
                var parser = new BitsParser(players);
                if (roster.IsFourPlayer)
                {
                    MatchResult4 matchResult = EventStoreSession.Load <MatchResult4>(roster.MatchResultId);
                    Parse4Result parseResult = parser.Parse4(bitsMatchResult, websiteConfig.ClubId);
                    update.Players = GetPlayerIds(parseResult);
                    bool isVerified = matchResult.Update(
                        PublishMessage,
                        roster,
                        parseResult.TeamScore,
                        parseResult.OpponentScore,
                        roster.BitsMatchId,
                        parseResult.CreateMatchSeries(),
                        players);
                    update.IsVerified = isVerified;
                }
                else
                {
                    MatchResult matchResult = EventStoreSession.Load <MatchResult>(roster.MatchResultId);
                    ParseResult parseResult = parser.Parse(bitsMatchResult, websiteConfig.ClubId);
                    update.Players = GetPlayerIds(parseResult);
                    var resultsForPlayer = DocumentSession.Query <ResultForPlayerIndex.Result, ResultForPlayerIndex>()
                                           .Where(x => x.Season == roster.Season)
                                           .ToArray()
                                           .ToDictionary(x => x.PlayerId);
                    MatchSerie[] matchSeries = parseResult.CreateMatchSeries();
                    bool         isVerified  = matchResult.Update(
                        PublishMessage,
                        roster,
                        parseResult.TeamScore,
                        parseResult.OpponentScore,
                        matchSeries,
                        parseResult.OpponentSeries,
                        players,
                        resultsForPlayer);
                    update.IsVerified = isVerified;
                }
            }

            roster.UpdateWith(Trace.CorrelationManager.ActivityId, update);
            return(Ok());
        }