/// <summary>
        /// Returns a list of all Champions in the current Version
        /// </summary>
        /// <param name="region">Region of data</param>
        public static List<Champion> GetAllChampions(string region)
        {
            var cacheName = "allChamps_" + region;
            var cached = HttpContext.Current.Cache[cacheName] as List<Champion>;

            if (cached != null)
                return cached;

            var client = ApiTools.GlobalApiClient();

            var request = new RestRequest(UrlFormat, Method.GET);

            request.AddUrlSegment("region", region);
            request.AddUrlSegment("method", "champion");

            request.AddParameter("dataById", true);

            request.AddApiKey();

            var response = client.Execute(request);
            var response2 = client.Execute<dynamic>(request);

            var champs = ParseAllChampsResponse(region, response.Content);

            HttpContext.Current.Cache[cacheName] = champs;

            return champs;
        }
        /// <summary>
        /// Grabs the details of a Match from the Riot API
        /// </summary>
        /// <param name="region">Region to fetch from</param>
        /// <param name="matchId">Id of the Match to fetch</param>
        /// <returns>MatchDetail object containing the details of the match</returns>
        public static MatchDetail GetMatch(string region, int matchId)
        {
            Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), "Loading Match " + matchId);

            // Load the match from our Cache if we can, as this is much faster and saves on API calls
            var cachedMatch = CacheService<MatchDetail>.GetFromCache("MatchCache", region, matchId);
            if (cachedMatch != null && cachedMatch.MatchId != 0)
            {
                cachedMatch.FromCache = true;
                return cachedMatch;
            }

            var client = ApiTools.ApiClient(region);

            var request = new RestRequest(UrlFormat, Method.GET);

            request.AddUrlSegment("region", region);
            request.AddUrlSegment("matchid", matchId.ToString());
            request.AddParameter("includeTimeline", true);

            request.AddApiKey();

            var response = client.Execute<MatchDetail>(request);

            //Check to see if we are approaching rate limiting
            if (response.StatusCode == HttpStatusCode.ServiceUnavailable || response.StatusCode.ToString() == "429")
            {
                Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), "Too many calls, briefly pausing. Headers: "
                    + String.Join(",", response.Headers));
                Thread.Sleep(Convert.ToInt32(ConfigurationManager.AppSettings["msBetweenApiCalls"])*2);
            }

            var match = response.Data;
            match.FromCache = false;

            Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), "ResponseCode: " + response.StatusCode);

            if (match.MatchId == 0)
                Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), "Warning: Did not correctly load Match " +
                    matchId + " Response: " + response.StatusDescription);
            else
                CacheService<MatchDetail>.WriteToCache("MatchCache", region, matchId, match);
                // Save match to file cache

            return match;
        }
        /// <summary>
        /// Fetches the URL used to grab CDN assets from DataDragon
        /// </summary>
        /// <param name="region">Region of data</param>
        /// <returns>DataDragon object containing data on the current Version of DataDragon</returns>
        public static DataDragon GetCdnUrl(string region)
        {
            var cacheName = "cdn_" + region;
            var cached = HttpContext.Current.Cache[cacheName] as DataDragon;

            if (cached != null)
                return cached;

            var client = ApiTools.GlobalApiClient();

            var request = new RestRequest(UrlFormat, Method.GET);

            request.AddUrlSegment("region", region);
            request.AddUrlSegment("method", "realm");

            request.AddApiKey();

            var response = client.Execute<DataDragon>(request);

            HttpContext.Current.Cache[cacheName] = response.Data;

            return response.Data;
        }
        /// <summary>
        /// Scrapes the Id's of current featured Matches in a region. Used to keep statistics up to date.
        /// This method is called externally.
        /// </summary>
        /// <param name="region"></param>
        public static void ScrapeCurrentFeaturedGames(string region)
        {
            Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), "Scraping current featured games");
            var client = ApiTools.ApiClient(region);
            var request =
                new RestRequest(
                    "/observer-mode/rest/featured",
                    Method.GET);

            request.AddApiKey();

            var response = client.Execute<FeaturedGames>(request);

            //Check to see if we are approaching rate limiting
            if (response.StatusCode == HttpStatusCode.ServiceUnavailable || response.StatusCode.ToString() == "429")
            {
                Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), "Too many calls, briefly pausing. Headers: "
                    + String.Join(",", response.Headers));
                Thread.Sleep(Convert.ToInt32(ConfigurationManager.AppSettings["msBetweenApiCalls"]) * 2);
            }

            var container = ApiTools.GetBlobContainer("matches");
            var blob = container.GetAppendBlobReference("matchIds.txt");

            if (!blob.Exists())
                blob.CreateOrReplace();

            foreach (var game in response.Data.GameList)
            {
                // Only scrape Ranked games on Summoner's Rift
                if ((game.GameQueueConfigId == 4 || game.GameQueueConfigId == 42) && game.MapId == 11)
                {
                    blob.AppendText(game.GameId.ToString() + "\n");
                }
            }

            Logger.LogMessageToFile(MethodBase.GetCurrentMethod().DeclaringType.ToString(), String.Format("Scrape complete, {0} games scraped", response.Data.GameList.Count));
        }
        /// <summary>
        /// Loads an Champion from cache or from the API
        /// </summary>
        /// <param name="region">Region of data</param>
        /// <param name="championId">ID of champion</param>
        public static Champion GetChampion(string region, int championId)
        {
            // Two layer caching: File and CurrentCache.
            var cacheName = "champ_" + region + "_" + championId;
            var cached = HttpContext.Current.Cache[cacheName] as Champion;

            if (cached != null)
                return cached;

            cached = CacheService<Champion>.GetFromCache("ChampionCache", region, championId);

            if (cached != null)
                return cached;

            var client = ApiTools.ApiClient(region);

            var request = new RestRequest(UrlFormat + "/{championid}", Method.GET);

            request.AddUrlSegment("region", region);
            request.AddUrlSegment("method", "champion");
            request.AddUrlSegment("championid", championId.ToString());

            request.AddParameter("champData", "image");

            request.AddApiKey();

            var response = client.Execute<Champion>(request);

            // Write to both File and Current cache
            CacheService<Champion>.WriteToCache("ChampionCache", region, championId, response.Data);
            HttpContext.Current.Cache[cacheName] = response.Data;

            return response.Data;
        }
        /// <summary>
        /// Loads an Item from cache or from the API
        /// </summary>
        /// <param name="region">Region of data</param>
        /// <param name="itemId">ID of item</param>
        public static Item GetItem(string region, long itemId)
        {
            // Two layer caching: File and CurrentCache.
            var cacheName = "item_" + region + "_" + itemId;
            var cached = HttpContext.Current.Cache[cacheName] as Item;

            if (cached != null)
                return cached;

            cached = CacheService<Item>.GetFromCache("ItemCache", region, (int)itemId);

            if (cached != null)
                return cached;

            var client = ApiTools.ApiClient(region);

            var request = new RestRequest(UrlFormat + "/{itemid}", Method.GET);

            request.AddUrlSegment("region", region);
            request.AddUrlSegment("method", "item");
            request.AddUrlSegment("itemid", itemId.ToString());

            request.AddParameter("itemData", "consumed,from,gold,into,image");

            request.AddApiKey();

            var response = client.Execute<Item>(request);

            // Write to both File and Current cache
            CacheService<Item>.WriteToCache("ItemCache", region, (int)itemId, response.Data);
            HttpContext.Current.Cache[cacheName] = response.Data;

            return response.Data;
        }