<commit_before>﻿using System.Threading.Tasks;
using SFA.DAS.ActiveDirectory;
using SFA.DAS.EmployerFinance.Configuration;
using SFA.DAS.EmployerFinance.Models.ExpiringFunds;
using SFA.DAS.NLog.Logger;
using SFA.DAS.Http;
using SFA.DAS.EmployerFinance.Models.ProjectedCalculations;
using System;

namespace SFA.DAS.EmployerFinance.Services
{
    public class DasForecastingService : IDasForecastingService
    {
        private readonly IHttpClientWrapper _httpClient;
        private readonly IAzureAdAuthenticationService _azureAdAuthService;
        private readonly ForecastingApiClientConfiguration _apiClientConfiguration;
        private readonly ILog _logger;

        public DasForecastingService(IHttpClientWrapper httpClient,
            IAzureAdAuthenticationService azureAdAuthService,
            ForecastingApiClientConfiguration apiClientConfiguration,
            ILog logger)
        {
            _httpClient = httpClient;
            _azureAdAuthService = azureAdAuthService;
            _apiClientConfiguration = apiClientConfiguration;
            _logger = logger;

            _httpClient.BaseUrl = _apiClientConfiguration.ApiBaseUrl;
            _httpClient.AuthScheme = "Bearer";
        }

        public async Task<ExpiringAccountFunds> GetExpiringAccountFunds(long accountId)
        {
            _logger.Info($"Getting expiring funds for account ID: {accountId}");

            return await CallAuthService<ExpiringAccountFunds>(
                $"/api/accounts/{accountId}/AccountProjection/expiring-funds",
                accountId,
                (ex) =>
                {
                    if (ex is ResourceNotFoundException)
                    {
                        _logger.Error(ex, $"Could not find expired funds for account ID: {accountId} when calling forecast API");
                    }
                }
                );
        }

        public async Task<ProjectedCalculation> GetProjectedCalculations(long accountId)
        {
            _logger.Info($"Getting projected calculations for account ID: {accountId}");

            return await CallAuthService<ProjectedCalculation>(
                $"/api/accounts/{accountId}/AccountProjection/projected-summary",
                accountId,
                (ex) =>
                {
                    if (ex is ResourceNotFoundException)
                    {
                        _logger.Error(ex, $"Could not find projected calculations for account ID: {accountId} when calling forecast API");
                    }
                }
                );
        }

        private async Task<T> CallAuthService<T>(string endpointUrl, long accountId, Action<Exception> OnError = null)
        {
            var accessToken = await _azureAdAuthService.GetAuthenticationResult(
                _apiClientConfiguration.ClientId,
                _apiClientConfiguration.ClientSecret,
                _apiClientConfiguration.IdentifierUri,
                _apiClientConfiguration.Tenant);

            try
            {
                var accountExpiredFunds =
                    await _httpClient.Get<T>(accessToken, endpointUrl);

                return accountExpiredFunds;
            }
            catch (ResourceNotFoundException ex)
            {
                OnError?.Invoke(ex);
                _logger.Error(ex, $"ResourceNotFoundException returned from forecast API for account ID: {accountId}");                
                return default(T);
            }
            catch (HttpException ex)
            {
                OnError?.Invoke(ex);

                switch (ex.StatusCode)
                {
                    case 400:
                        _logger.Error(ex, $"Bad request sent to forecast API for account ID: {accountId}");<commit_msg>CON-542-minor-change<commit_after>﻿using System.Threading.Tasks;
using SFA.DAS.ActiveDirectory;
using SFA.DAS.EmployerFinance.Configuration;
using SFA.DAS.EmployerFinance.Models.ExpiringFunds;
using SFA.DAS.NLog.Logger;
using SFA.DAS.Http;
using SFA.DAS.EmployerFinance.Models.ProjectedCalculations;
using System;

namespace SFA.DAS.EmployerFinance.Services
{
    public class DasForecastingService : IDasForecastingService
    {
        private readonly IHttpClientWrapper _httpClient;
        private readonly IAzureAdAuthenticationService _azureAdAuthService;
        private readonly ForecastingApiClientConfiguration _apiClientConfiguration;
        private readonly ILog _logger;

        public DasForecastingService(IHttpClientWrapper httpClient,
            IAzureAdAuthenticationService azureAdAuthService,
            ForecastingApiClientConfiguration apiClientConfiguration,
            ILog logger)
        {
            _httpClient = httpClient;
            _azureAdAuthService = azureAdAuthService;
            _apiClientConfiguration = apiClientConfiguration;
            _logger = logger;

            _httpClient.BaseUrl = _apiClientConfiguration.ApiBaseUrl;
            _httpClient.AuthScheme = "Bearer";
        }

        public async Task<ExpiringAccountFunds> GetExpiringAccountFunds(long accountId)
        {
            _logger.Info($"Getting expiring funds for account ID: {accountId}");

            return await CallAuthService<ExpiringAccountFunds>(
                $"/api/accounts/{accountId}/AccountProjection/expiring-funds",
                accountId,
                (ex) =>
                {
                    if (ex is ResourceNotFoundException)
                    {
                        _logger.Error(ex, $"Could not find expired funds for account ID: {accountId} when calling forecast API");
                    }
                }
                );
        }

        public async Task<ProjectedCalculation> GetProjectedCalculations(long accountId)
        {
            _logger.Info($"Getting projected calculations for account ID: {accountId}");

            return await CallAuthService<ProjectedCalculation>(
                $"/api/accounts/{accountId}/AccountProjection/projected-summary",
                accountId,
                (ex) =>
                {
                    if (ex is ResourceNotFoundException)
                    {
                        _logger.Error(ex, $"Could not find projected calculations for account ID: {accountId} when calling forecast API");
                    }
                }
                );
        }

        private async Task<T> CallAuthService<T>(string endpointUrl, long accountId, Action<Exception> OnError = null)
        {
            var accessToken = await _azureAdAuthService.GetAuthenticationResult(
                _apiClientConfiguration.ClientId,
                _apiClientConfiguration.ClientSecret,
                _apiClientConfiguration.IdentifierUri,
                _apiClientConfiguration.Tenant);

            try
            {
                return await _httpClient.Get<T>(accessToken, endpointUrl);
            }
            catch (ResourceNotFoundException ex)
            {
                OnError?.Invoke(ex);
                _logger.Error(ex, $"ResourceNotFoundException returned from forecast API for account ID: {accountId}");                
                return default(T);
            }
            catch (HttpException ex)
            {
                OnError?.Invoke(ex);

                switch (ex.StatusCode)
                {
                    case 400:
                        _logger.Error(ex, $"Bad request sent to forecast API for account ID: {accountId}");
{'fraction_non_alphanumeric': 0.06907147628590514, 'fraction_numerical': 0.0012024048096192384, 'mean_word_length': 1.8847784200385356, 'pattern_counts': {'":': 0, '<': 19, '<?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': '4553937', 'n_tokens_mistral': 1872, 'n_tokens_neox': 1738, 'n_words': 380}