using Shogi.Contracts.Api; using Shogi.Contracts.Types; using Shogi.UI.Pages.Home.Account; using System.Net; using System.Net.Http.Json; using System.Text.Json; namespace Shogi.UI.Pages.Home.Api { public class ShogiApi : IShogiApi { public const string GuestClientName = "Guest"; public const string MsalClientName = "Msal"; private readonly JsonSerializerOptions serializerOptions; private readonly AccountState accountState; private readonly HttpClient guestHttpClient; private readonly HttpClient msalHttpClient; public ShogiApi(IHttpClientFactory clientFactory, AccountState accountState) { Console.WriteLine("ShogiApi constructor"); this.serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); this.accountState = accountState; this.guestHttpClient = clientFactory.CreateClient(GuestClientName); this.msalHttpClient = clientFactory.CreateClient(MsalClientName); } private HttpClient HttpClient => accountState.User?.WhichAccountPlatform switch { WhichAccountPlatform.Guest => this.guestHttpClient, WhichAccountPlatform.Microsoft => this.msalHttpClient, _ => throw new InvalidOperationException("AccountState.User must not be null during API call.") }; public async Task GuestLogout() { var response = await this.guestHttpClient.PutAsync(new Uri("User/GuestLogout", UriKind.Relative), null); response.EnsureSuccessStatusCode(); } public async Task GetSession(string name) { var response = await HttpClient.GetAsync(new Uri($"Sessions/{name}", UriKind.Relative)); if (response.IsSuccessStatusCode) { return (await response.Content.ReadFromJsonAsync(serializerOptions))?.Session; } return null; } public async Task GetSessionsPlayerCount() { var response = await HttpClient.GetAsync(RelativeUri("Sessions/PlayerCount")); if (response.IsSuccessStatusCode) { return await response.Content.ReadFromJsonAsync(serializerOptions); } return null; } /// /// Logs the user into the API and returns a token which can be used to request a socket connection. /// public async Task GetToken(WhichAccountPlatform whichAccountPlatform) { var httpClient = whichAccountPlatform == WhichAccountPlatform.Microsoft ? this.msalHttpClient : this.guestHttpClient; var response = await httpClient.GetAsync(RelativeUri("User/Token")); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); if (!string.IsNullOrEmpty(content)) { return await response.Content.ReadFromJsonAsync(serializerOptions); } } return null; } public async Task Move(string sessionName, MovePieceCommand command) { await this.HttpClient.PatchAsync(RelativeUri($"Sessions/{sessionName}/Move"), JsonContent.Create(command)); } public async Task PostSession(string name, bool isPrivate) { var response = await HttpClient.PostAsJsonAsync(RelativeUri("Sessions"), new CreateSessionCommand { Name = name, }); return response.StatusCode; } public Task PatchJoinGame(string name) { return HttpClient.PatchAsync(RelativeUri($"Sessions/{name}/Join"), null); } private static Uri RelativeUri(string path) => new Uri(path, UriKind.Relative); } }