using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using KTUSAPS.Data; using KTUSAPS.Data.Model; using KTUSAPS.Extensions; using Microsoft.AspNetCore.Authorization; namespace KTUSAPS.Controllers { [Route("api/[controller]")] [ApiController] public class PublishedProblemsController : ControllerBase { private readonly SAPSDataContext _context; public PublishedProblemsController(SAPSDataContext context) { _context = context; } [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] public async Task>> GetPublishedProblems() { return await _context.PublishedProblems.ToListAsync(); } [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [Authorize("admin")] public async Task> CreatePublishedProblem([FromBody] PublishedProblem publishedProblem) { if (publishedProblem == null) return BadRequest("No data provided for object to be created."); if (publishedProblem.Id != default) return BadRequest("Id has been set on create request, please do not do that, set id to 0 or ommit it."); if (publishedProblem.Issue != null || publishedProblem.Solution != null || publishedProblem.Votes != null) return BadRequest("Do not provide navigation property values."); _context.PublishedProblems.Add(publishedProblem); await _context.SaveChangesAsync(); return CreatedAtAction(nameof(GetPublishedProblem), new { id = publishedProblem.Id }, publishedProblem); } [HttpGet("{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetPublishedProblem(int id) { var publishedProblem = await _context.PublishedProblems.FindAsync(id); if (publishedProblem == null) return NotFound(); return publishedProblem; } [HttpPatch("{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize("admin")] public async Task> UpdatePublishedProblem(int id, PublishedProblem publishedProblem) { var databasePublishedProblem = await _context.PublishedProblems.FindAsync(id); if (databasePublishedProblem == default) return NotFound(); var ePublishedProblem = _context.Attach(databasePublishedProblem); ePublishedProblem.MovePropertyDataWhiteList(publishedProblem, new string[] { nameof(databasePublishedProblem.ProblemLt), nameof(databasePublishedProblem.ProblemEn), nameof(databasePublishedProblem.Created), nameof(databasePublishedProblem.IssueId), nameof(databasePublishedProblem.SolutionId), }); await _context.SaveChangesAsync(); return Ok(ePublishedProblem.Entity); } [HttpDelete("{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize("admin")] public async Task DeletePublishedProblem(int id) { var publishedProblem = await _context.PublishedProblems.FindAsync(id); if (publishedProblem == null) return NotFound(); _context.PublishedProblems.Remove(publishedProblem); await _context.SaveChangesAsync(); return NoContent(); } [HttpGet("{id}/Votes")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetVoteCount(int id) { var publishedProblem = await _context.PublishedProblems.FindAsync(id); if (publishedProblem == null) return NotFound(); return (await _context.Votes .Where(v => v.ProblemId == publishedProblem.Id) .ToListAsync()) .Count(); } [HttpPost("{id}/Votes")] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize] public async Task> Vote(int id) { var publishedProblem = await _context.PublishedProblems.FindAsync(id); if (publishedProblem == null) return NotFound(); var vote = new Vote() { Problem = publishedProblem, UserId = User.GetUserId(), }; _context.Votes.Add(vote); await _context.SaveChangesAsync(); return CreatedAtAction(nameof(GetVote), new { id = id, userId = vote.UserId }, vote); } [HttpPost("{id}/Votes/{userId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetVote(int id, string userId) { var publishedProblem = await _context.PublishedProblems.FindAsync(id); if (publishedProblem == null) return NotFound(); var vote = await _context.Votes .Where(v => v.ProblemId == publishedProblem.Id && v.UserId == userId) .FirstOrDefaultAsync(); if (vote == default) return NotFound(); return vote; } } }