FootballResultControllerBase.java

package com.mojosoft.demo.controller.base;

import com.mojosoft.demo.dto.FootballResultDTO;
import com.mojosoft.demo.dto.FootballResultJsonDTO;
import com.mojosoft.demo.dto.UploadResponseDTO;
import com.mojosoft.demo.service.base.FootballResultServiceI;
import io.swagger.annotations.ApiOperation;
import jakarta.validation.Valid;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * Controller base class for testing football results with and without cache.
 */
@Slf4j
public class FootballResultControllerBase {

  private final FootballResultServiceI resultService;

  public FootballResultControllerBase(FootballResultServiceI resultService) {
    this.resultService = resultService;
  }

  @GetMapping
  @ApiOperation(value = "Get football result by season")
  public ResponseEntity<List<FootballResultDTO>> getAll() {
    List<FootballResultDTO> result = resultService.getAll();
    return ResponseEntity.ok(result);
  }

  /**
   * This method gets the football result by season.
   *
   * @param season the season
   * @return the {@link ResponseEntity} object
   */
  @GetMapping("/season/{season}")
  @ApiOperation(value = "Get football result by season")
  public ResponseEntity<List<FootballResultDTO>> getFootballResultsBySeason(
      @PathVariable String season) {
    season = URLDecoder.decode(season, StandardCharsets.UTF_8);
    List<FootballResultDTO> result = resultService.getBySeason(season);
    return ResponseEntity.ok(result);
  }

  /**
   * This method gets the football result by season and teams.
   *
   * @param season the season
   * @param homeTeam the home team
   * @param awayTeam the away team
   * @return the {@link ResponseEntity} object
   */
  @GetMapping("/season/{season}/home_team/{homeTeam}/away_team/{awayTeam}")
  @ApiOperation(value = "Get football result by season and teams")
  public ResponseEntity<FootballResultDTO> getFootballResultByMatch(
      @PathVariable String season,
      @PathVariable String homeTeam,
      @PathVariable String awayTeam) {

    final String decodedSeason = URLDecoder.decode(season, StandardCharsets.UTF_8);
    final String decodedHomeTeam = URLDecoder.decode(homeTeam, StandardCharsets.UTF_8);
    final String decodedAwayTeam = URLDecoder.decode(awayTeam, StandardCharsets.UTF_8);

    return resultService.getByMatch(decodedSeason, decodedHomeTeam, decodedAwayTeam)
        .map(ResponseEntity::ok)
        .orElseGet(() -> {
          log.warn("Result not found for season: {}, homeTeam: {}, awayTeam: {}",
              decodedSeason, decodedHomeTeam, decodedAwayTeam);
          return ResponseEntity.notFound().build();
        });
  }

  /**
   * This method saves the football results.
   *
   * @param results the list of {@link FootballResultJsonDTO} objects
   * @return the {@link ResponseEntity} object
   */
  @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
  @PutMapping
  @ApiOperation(value = "Save/Update football result")
  public ResponseEntity<UploadResponseDTO> putFootballResultsNoCache(
      @RequestBody @Valid List<FootballResultJsonDTO> results) {
    try {
      log.debug("Updating football results");
      UploadResponseDTO uploadResponseDTO = this.resultService.save(results);
      return ResponseEntity.status(HttpStatus.CREATED).body(uploadResponseDTO);
    } catch (Exception e) {
      log.error("Error processing football results", e);
      return ResponseEntity.badRequest().body(createErrorResponse(e));
    }
  }

  /**
   * This method creates the upload error response.
   *
   * @param e the exception
   * @return the {@link UploadResponseDTO} object
   */
  private UploadResponseDTO createErrorResponse(Exception e) {
    UploadResponseDTO.ErrorDetails errorDetails =
        new UploadResponseDTO.ErrorDetails(e.getMessage(), e.getClass().getSimpleName());
    return new UploadResponseDTO(0, "Failed to save entries", errorDetails);
  }
}