<commit_before>﻿#if !DISABLE_PLAYFABCLIENT_API && !DISABLE_PLAYFABENTITY_API
namespace PlayFab.QoS
{
    using EventsModels;
    using MultiplayerModels;
    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    public class PlayFabQosApi
    {
        private readonly PlayFabAuthenticationContext _authContext;
        private const int DefaultPingsPerRegion = 10;
        private const int DefaultDegreeOfParallelism = 4;
        private const int NumTimeoutsForError = 3;
        private const int DefaultTimeoutMs = 250;

        private readonly PlayFabMultiplayerInstanceAPI multiplayerApi;
        private readonly PlayFabEventsInstanceAPI eventsApi;

        private readonly Func<object, Task> qosResultsReporter;

        private Dictionary<string, string> _dataCenterMap;

        private bool _reportResults;

        public PlayFabQosApi(PlayFabApiSettings settings = null, PlayFabAuthenticationContext authContext = null, bool reportResults = true)
        {
            _authContext = authContext ?? PlayFabSettings.staticPlayer;

            multiplayerApi = new PlayFabMultiplayerInstanceAPI(settings, _authContext);
            eventsApi = new PlayFabEventsInstanceAPI(settings, _authContext);
            qosResultsReporter = SendSuccessfulQosResultsToPlayFab;
            _reportResults = reportResults;
        }

#pragma warning disable 4014
        public async Task<QosResult> GetQosResultAsync(
            int timeoutMs = DefaultTimeoutMs,
            int pingsPerRegion = DefaultPingsPerRegion,
            int degreeOfParallelism = DefaultDegreeOfParallelism)
        {
            await new PlayFabUtil.SynchronizationContextRemover();

            QosResult result = await GetResultAsync(timeoutMs, pingsPerRegion, degreeOfParallelism);
            if (result.ErrorCode != (int)QosErrorCode.Success)
            {
                return result;
            }

            if (_reportResults)
            {
                Task.Factory.StartNew(qosResultsReporter, result).Unwrap();
            }

            return result;
        }
#pragma warning restore 4014

        private async Task<QosResult> GetResultAsync(int timeoutMs, int pingsPerRegion, int degreeOfParallelism)
        {
            if (!_authContext.IsClientLoggedIn())
            {
                return new QosResult
                {
                    ErrorCode = (int)QosErrorCode.NotLoggedIn,
                    ErrorMessage = "Client is not logged in"
                };
            }

            Dictionary<string, string> dataCenterMap = await GetQoSServerList();

            if (dataCenterMap == null || dataCenterMap.Count == 0)
            {
                return new QosResult
                {
                    ErrorCode = (int)QosErrorCode.FailedToRetrieveServerList,
                    ErrorMessage = "Failed to get server list from PlayFab multiplayer servers"
                };
            }

            return await GetSortedRegionLatencies(timeoutMs, dataCenterMap, pingsPerRegion, degreeOfParallelism);
        }

        private async Task<Dictionary<string, string>> GetQoSServerList()
        {
            if (_dataCenterMap?.Count > 0)
            {
                // If the dataCenterMap is already initialized, return
                return _dataCenterMap;
            }

            var request = new ListQosServersRequest();
            PlayFabResult<ListQosServersResponse> response = await multiplayerApi.ListQosServersAsync(request);

            if (response == null || response.Error != null)
            {
                return null;
            }

            var dataCenterMap = new Dictionary<string, string>(response.Result.QosServers.Count);

            foreach (QosServer qosServer in response.Result.QosServers)
            {
                if (!string.IsNullOrEmpty(qosServer.Region))
                {
                    dataCenterMap[qosServer.Region] = qosServer.ServerUrl;<commit_msg>Modify the SDKGenerator template to use the newer ListQosServersForTitle() API (#697)<commit_after>﻿#if !DISABLE_PLAYFABCLIENT_API && !DISABLE_PLAYFABENTITY_API
namespace PlayFab.QoS
{
    using EventsModels;
    using MultiplayerModels;
    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;

    public class PlayFabQosApi
    {
        private readonly PlayFabAuthenticationContext _authContext;
        private const int DefaultPingsPerRegion = 10;
        private const int DefaultDegreeOfParallelism = 4;
        private const int NumTimeoutsForError = 3;
        private const int DefaultTimeoutMs = 250;

        private readonly PlayFabMultiplayerInstanceAPI multiplayerApi;
        private readonly PlayFabEventsInstanceAPI eventsApi;

        private readonly Func<object, Task> qosResultsReporter;

        private Dictionary<string, string> _dataCenterMap;

        private bool _reportResults;

        public PlayFabQosApi(PlayFabApiSettings settings = null, PlayFabAuthenticationContext authContext = null, bool reportResults = true)
        {
            _authContext = authContext ?? PlayFabSettings.staticPlayer;

            multiplayerApi = new PlayFabMultiplayerInstanceAPI(settings, _authContext);
            eventsApi = new PlayFabEventsInstanceAPI(settings, _authContext);
            qosResultsReporter = SendSuccessfulQosResultsToPlayFab;
            _reportResults = reportResults;
        }

#pragma warning disable 4014
        public async Task<QosResult> GetQosResultAsync(
            int timeoutMs = DefaultTimeoutMs,
            int pingsPerRegion = DefaultPingsPerRegion,
            int degreeOfParallelism = DefaultDegreeOfParallelism)
        {
            await new PlayFabUtil.SynchronizationContextRemover();

            QosResult result = await GetResultAsync(timeoutMs, pingsPerRegion, degreeOfParallelism);
            if (result.ErrorCode != (int)QosErrorCode.Success)
            {
                return result;
            }

            if (_reportResults)
            {
                Task.Factory.StartNew(qosResultsReporter, result).Unwrap();
            }

            return result;
        }
#pragma warning restore 4014

        private async Task<QosResult> GetResultAsync(int timeoutMs, int pingsPerRegion, int degreeOfParallelism)
        {
            if (!_authContext.IsClientLoggedIn())
            {
                return new QosResult
                {
                    ErrorCode = (int)QosErrorCode.NotLoggedIn,
                    ErrorMessage = "Client is not logged in"
                };
            }

            Dictionary<string, string> dataCenterMap = await GetQoSServerList();

            if (dataCenterMap == null || dataCenterMap.Count == 0)
            {
                return new QosResult
                {
                    ErrorCode = (int)QosErrorCode.FailedToRetrieveServerList,
                    ErrorMessage = "Failed to get server list from PlayFab multiplayer servers"
                };
            }

            return await GetSortedRegionLatencies(timeoutMs, dataCenterMap, pingsPerRegion, degreeOfParallelism);
        }

        private async Task<Dictionary<string, string>> GetQoSServerList()
        {
            if (_dataCenterMap?.Count > 0)
            {
                // If the dataCenterMap is already initialized, return
                return _dataCenterMap;
            }

            var request = new ListQosServersForTitleRequest();
            PlayFabResult<ListQosServersForTitleResponse> response = await multiplayerApi.ListQosServersForTitleAsync(request);

            if (response == null || response.Error != null)
            {
                return null;
            }

            var dataCenterMap = new Dictionary<string, string>(response.Result.QosServers.Count);

            foreach (QosServer qosServer in response.Result.QosServers)
            {
                if (!string.IsNullOrEmpty(qosServer.Region))
                {
                    dataCenterMap[qosServer.Region] = qosServer.ServerUrl;
{'fraction_non_alphanumeric': 0.0628508664876739, 'fraction_numerical': 0.004515499145716377, 'mean_word_length': 2.1628714781937477, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '826672', 'n_tokens_mistral': 2114, 'n_tokens_neox': 1991, 'n_words': 471}