using System.Net; using System.Net.Http.Headers; using System.Text; using System.Text.Json; using Contracts; using Contracts.Menu; using Contracts.Orders; using Contracts.Requests; using Contracts.Responses; using Domain.Entities; namespace ApiClient.Http; public sealed class HttpSmsClient : ISmsClient, IDisposable { private readonly HttpClient _httpClient; public HttpSmsClient(HttpSmsClientOptions options) { _httpClient = new HttpClient { BaseAddress = new Uri(options.BaseUrl) }; var credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{options.Username}:{options.Password}")); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials); } public async Task GetMenuAsync(bool withPrice = true, CancellationToken cancellationToken = default) { var request = new GetMenuApiRequest { CommandParameters = new GetMenuParameters(withPrice), }; var response = await SendAsync(request, cancellationToken); return ToGetMenuResponse(response); } public async Task SendOrderAsync(Order order, CancellationToken cancellationToken = default) { var request = new SendOrderApiRequest { CommandParameters = new SendOrderParameters { OrderId = order.Id.ToString(), MenuItems = order.Items.ToList(), }, }; var response = await SendAsync(request, cancellationToken); return ToSendOrderResponse(response); } public void Dispose() => _httpClient.Dispose(); private async Task SendAsync(ApiRequest request, CancellationToken cancellationToken) { var json = JsonSerializer.Serialize(request, request.GetType(), ApiJsonOptions.Instance); using var content = new StringContent(json, Encoding.UTF8, "application/json"); using var httpResponse = await _httpClient.PostAsync("/", content, cancellationToken); if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) { return new ApiResponse { Command = request.Command, Success = false, ErrorMessage = "Требуется аутентификация.", }; } var responseJson = await httpResponse.Content.ReadAsStringAsync(cancellationToken); if (string.IsNullOrWhiteSpace(responseJson)) { return new ApiResponse { Command = request.Command, Success = false, ErrorMessage = $"Пустой ответ сервера (HTTP {(int)httpResponse.StatusCode}).", }; } try { return ApiResponseDeserializer.Deserialize(responseJson); } catch (JsonException) { return new ApiResponse { Command = request.Command, Success = false, ErrorMessage = $"Некорректный JSON в ответе (HTTP {(int)httpResponse.StatusCode}): {responseJson}", }; } } private static GetMenuApiResponse ToGetMenuResponse(ApiResponse response) => response as GetMenuApiResponse ?? new GetMenuApiResponse { Command = Commands.GetMenu, Success = false, ErrorMessage = response.ErrorMessage, }; private static SendOrderApiResponse ToSendOrderResponse(ApiResponse response) => response as SendOrderApiResponse ?? new SendOrderApiResponse { Command = Commands.SendOrder, Success = false, ErrorMessage = response.ErrorMessage, }; }