Files
Shogi/Shogi.UI/Pages/Home/Api/ShogiApi.cs
2024-01-29 13:00:20 -06:00

105 lines
4.0 KiB
C#

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(RelativeUri("User/TestGuestLogout"), null);
response.EnsureSuccessStatusCode();
}
public async Task<Session?> GetSession(string name)
{
var response = await HttpClient.GetAsync(new Uri($"Sessions/{name}", UriKind.Relative));
if (response.IsSuccessStatusCode)
{
return (await response.Content.ReadFromJsonAsync<ReadSessionResponse>(serializerOptions))?.Session;
}
return null;
}
public async Task<ReadSessionsPlayerCountResponse?> GetSessionsPlayerCount()
{
var response = await HttpClient.GetAsync(RelativeUri("Sessions/PlayerCount"));
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadFromJsonAsync<ReadSessionsPlayerCountResponse>(serializerOptions);
}
return null;
}
/// <summary>
/// Logs the user into the API and returns a token which can be used to request a socket connection.
/// </summary>
public async Task<CreateTokenResponse?> 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 JsonSerializer.Deserialize<CreateTokenResponse>(content, 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<HttpStatusCode> PostSession(string name, bool isPrivate)
{
var response = await HttpClient.PostAsJsonAsync(RelativeUri("Sessions"), new CreateSessionCommand
{
Name = name,
});
return response.StatusCode;
}
public Task<HttpResponseMessage> PatchJoinGame(string name)
{
return HttpClient.PatchAsync(RelativeUri($"Sessions/{name}/Join"), null);
}
private static Uri RelativeUri(string path) => new Uri(path, UriKind.Relative);
}
}