using System.Net.Http.Json;
using System.Text.Json;
using GB5Shared.DTO.Framework.Login;
using Microsoft.Extensions.Logging;
namespace SwBLL.Integration;
/// Mirrors EntitlementBLL.Onboarding.SqlWorkbenchClient's exact shape (IHttpClientFactory,
/// a named client, JSON GET, Login-header convention) for the reverse direction — SqlWorkbench
/// calling INTO Entitlement (tracker §40) instead of Entitlement calling into SqlWorkbench.
public class EntitlementSubscriptionClient : IEntitlementSubscriptionClient
{
private readonly IHttpClientFactory _HttpClientFactory;
private readonly ILogger _Logger;
public EntitlementSubscriptionClient(IHttpClientFactory httpClientFactory, ILogger logger)
{
_HttpClientFactory = httpClientFactory;
_Logger = logger;
}
public async Task GetSnapshotAsync(int clientId, LoginDTO swLogin, CancellationToken ct)
{
var client = _HttpClientFactory.CreateClient("Entitlement");
// Only ClientId carries meaning for this call — DatabaseName is Entitlement's own
// concern to resolve server-side, not something SqlWorkbench should dictate (unlike the
// reverse direction, where Entitlement must explicitly override DatabaseName to
// "Gb5System" since it knows SW's schema lives there — SqlWorkbench has no equivalent
// fixed knowledge of which physical database backs Entitlement in a given deployment).
var login = new LoginDTO { ClientId = swLogin.ClientId, UserId = swLogin.UserId };
client.DefaultRequestHeaders.Remove("Login");
client.DefaultRequestHeaders.Add("Login", JsonSerializer.Serialize(login));
HttpResponseMessage response;
try
{
response = await client.GetAsync($"/lic/Subscription.svc/GetClientEntitlementSnapshot?ClientId={clientId}", ct)
.ConfigureAwait(false);
}
catch (HttpRequestException ex)
{
_Logger.LogError(ex, "Entitlement GetClientEntitlementSnapshot call failed for ClientId {ClientId}.", clientId);
throw new InvalidOperationException($"Could not reach Entitlement to resolve entitlement snapshot for ClientId {clientId}.", ex);
}
var raw = await response.Content.ReadAsStringAsync(ct).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
_Logger.LogError("Entitlement GetClientEntitlementSnapshot returned {StatusCode} for ClientId {ClientId}: {Body}",
response.StatusCode, clientId, raw);
throw new InvalidOperationException($"Entitlement GetClientEntitlementSnapshot failed ({(int)response.StatusCode}) for ClientId {clientId}.");
}
using var doc = JsonDocument.Parse(raw);
if (!doc.RootElement.TryGetProperty("Body", out var body) || body.ValueKind != JsonValueKind.Object)
return null; // Entitlement has nothing for this client — caller treats as "cannot determine"
return body.Deserialize(new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
}