private async Task <TvDbClient> GetTvDbClient(string language)
        {
            var normalizedLanguage = TvdbUtils.NormalizeLanguage(language) ?? DefaultLanguage;

            var tvDbClientInfo = _tvDbClients.GetOrAdd(normalizedLanguage, key => new TvDbClientInfo(_httpClientFactory, key));

            var tvDbClient = tvDbClientInfo.Client;

            // First time authenticating if the token was never updated or if it's empty in the client
            if (tvDbClientInfo.TokenUpdatedAt == DateTime.MinValue || string.IsNullOrEmpty(tvDbClient.Authentication.Token))
            {
                await tvDbClientInfo.TokenUpdateLock.WaitAsync().ConfigureAwait(false);

                try
                {
                    if (string.IsNullOrEmpty(tvDbClient.Authentication.Token))
                    {
                        await tvDbClient.Authentication.AuthenticateAsync(ApiKey).ConfigureAwait(false);

                        tvDbClientInfo.TokenUpdatedAt = DateTime.UtcNow;
                    }
                }
                finally
                {
                    tvDbClientInfo.TokenUpdateLock.Release();
                }
            }

            // Refresh if necessary
            if (tvDbClientInfo.TokenUpdatedAt < DateTime.UtcNow.Subtract(TimeSpan.FromHours(20)))
            {
                await tvDbClientInfo.TokenUpdateLock.WaitAsync().ConfigureAwait(false);

                try
                {
                    if (tvDbClientInfo.TokenUpdatedAt < DateTime.UtcNow.Subtract(TimeSpan.FromHours(20)))
                    {
                        try
                        {
                            await tvDbClient.Authentication.RefreshTokenAsync().ConfigureAwait(false);
                        }
                        catch
                        {
                            await tvDbClient.Authentication.AuthenticateAsync(ApiKey).ConfigureAwait(false);
                        }

                        tvDbClientInfo.TokenUpdatedAt = DateTime.UtcNow;
                    }
                }
                finally
                {
                    tvDbClientInfo.TokenUpdateLock.Release();
                }
            }

            return(tvDbClient);
        }
        private async Task <T> TryGetValue <T>(string key, string?language, Func <Task <T> > resultFactory)
        {
            if (_cache.TryGetValue(key, out T cachedValue))
            {
                return(cachedValue);
            }

            _tvDbClient.AcceptedLanguage = TvdbUtils.NormalizeLanguage(language) ?? DefaultLanguage;
            var result = await resultFactory.Invoke().ConfigureAwait(false);

            _cache.Set(key, result, TimeSpan.FromHours(1));
            return(result);
        }