using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Shogi.Api.Application; using Shogi.Api.Extensions; using Shogi.Api.Identity; using Shogi.Api.Repositories; using Shogi.Contracts.Api; using Shogi.Contracts.Types; using System.Security.Claims; namespace Shogi.Api.Controllers; [Authorize] [ApiController] [Route("[controller]")] public class SessionsController( SessionRepository sessionRepository, ShogiApplication application) : ControllerBase { [HttpPost] public async Task CreateSession() { var id = this.User.GetId(); if (string.IsNullOrEmpty(id)) { return this.Unauthorized(); } return await application.CreateSession(id); } [HttpDelete("{sessionId}")] public async Task DeleteSession(string sessionId) { var id = this.User.GetId(); if (id == null) { return this.Unauthorized(); } var (session, _) = await sessionRepository.ReadSessionAndMoves(sessionId); if (!session.HasValue) return this.NoContent(); if (session.Value.Player1Id == id) { await sessionRepository.DeleteSession(sessionId); return this.NoContent(); } return this.StatusCode(StatusCodes.Status403Forbidden, "Cannot delete sessions created by others."); } /// /// Fetch the session and latest board state. Also subscribe the user to socket events for this session. /// /// /// [HttpGet("{sessionId}")] public async Task> GetSession(Guid sessionId) { var session = await application.ReadSession(sessionId.ToString()); if (session == null) return this.NotFound(); return new Session { BoardState = new BoardState { Board = session.Board.BoardState.State.ToContract(), Player1Hand = session.Board.BoardState.Player1Hand.ToContract(), Player2Hand = session.Board.BoardState.Player2Hand.ToContract(), PlayerInCheck = session.Board.BoardState.InCheck?.ToContract(), WhoseTurn = session.Board.BoardState.WhoseTurn.ToContract() }, Player1 = application.GetUsername(session.Player1), Player2 = application.GetUsername(session.Player2), SessionId = session.Id }; } [HttpGet()] public async Task> ReadAllSessionsMetadata() { var id = this.User.GetId(); if (id == null) return this.Unauthorized(); var dtos = await application.ReadAllSessionMetadatas(id); return dtos .Select(dto => new SessionMetadata { Player1 = application.GetUsername(dto.Player1Id), Player2 = application.GetUsername(dto.Player2Id), SessionId = Guid.Parse(dto.Id), }) .ToArray(); } [HttpPatch("{sessionId}/Join")] public async Task JoinSession(string sessionId) { var id = this.User.GetId(); if (id == null) { return this.Unauthorized(); } return await application.JoinSession(sessionId, id); } [HttpPatch("{sessionId}/Move")] public async Task Move([FromRoute] string sessionId, [FromBody] MovePieceCommand command) { var id = this.User.GetId(); if (id == null) { return this.Unauthorized(); } return await application.MovePiece(id, sessionId, command); } }