package movie.apis; import com.google.gson.*; import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.Map; public class MovieService { private final static String GENRES_URL = "https://api.meshcomp.ir/api/v1/genres"; private final static HttpClient client = HttpClient.newHttpClient(); private Map moviesCache = new HashMap<>(); private boolean isMoviesLoaded = false; private int totalMovies = 0; private int totalPages = 0; private String getGenresList() { try { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(GENRES_URL)) .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { System.out.println("Genres List received successfully"); return response.body(); } else { throw new IOException("HTTP error code: " + response.statusCode()); } } catch (Exception e) { System.out.println("!!Exception : " + e.getMessage()); } return null; } private String getMoviesByGenreList(Long genreId, Long page) { try { String url = "https://api.meshcomp.ir/api/v1/genres/" + genreId + "/movies?page=" + page; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(url)) .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() == 200) { return response.body(); } else { System.out.println("HTTP error code: " + response.statusCode()); return null; } } catch (Exception e) { System.out.println("!!Exception : " + e.getMessage()); } return null; } public void displayGenres() { String jsonResponse = getGenresList(); if (jsonResponse == null) { System.out.println("Failed to get genres"); return; } try { JsonObject rootObject = JsonParser.parseString(jsonResponse).getAsJsonObject(); JsonArray genresArray = rootObject.getAsJsonArray("genres"); Type genreListType = new TypeToken>(){}.getType(); Gson gson = new Gson(); List genres = gson.fromJson(genresArray, genreListType); System.out.println("\nALL GENRES:"); for (Genre genre : genres) { System.out.println(genre.getId() + ". " + genre.getName()); } System.out.println(); } catch (Exception e) { System.err.println("ERROR parsing genres: " + e.getMessage()); } } /** * TODO 1: Display movies for a specific genre and page * * JSON format: { "movies": [ { "id": 1, "title": "Movie", "year": "1994" } ], "total": 177, "total_pages": 18 } * * Steps: * - Call getMoviesByGenreList(genreId, page) to get JSON * - Parse JSON to JsonObject * - Get "movies" array (NOT "data") * - Loop through array and print: "ID: {id} | {title} ({year})" * - Also print total and total_pages * * PUT ALL PARSING CODE INSIDE try-catch */ public void displayMoviesByGenre(Long genreId, Long page) { // TODO: Write your code here // All parsing code must be inside try-catch try { // Your code here } catch (Exception e) { System.err.println("ERROR: " + e.getMessage()); } } /** * TODO 2: Load all movies into cache (called automatically when needed) * * Steps: * - if (isMoviesLoaded) return; (already loaded) * - Clear moviesCache * - Get first page of genre 2 (Drama) to find total_pages * - Loop through all pages (1 to total_pages) * - For each page, get "movies" array * - Extract: id, title, year, poster, genres array * - For genres, loop and convert each string to Genre object * - Store in moviesCache using id as key * - Set isMoviesLoaded = true * * PUT ALL PARSING CODE INSIDE try-catch */ private void loadAllMovies() { // TODO: Write your code here // All parsing code must be inside try-catch try { // Your code here } catch (Exception e) { System.err.println("ERROR loading movies: " + e.getMessage()); } } /** * TODO 3: Display all movies with pagination * * Steps: * - Call loadAllMovies() first * - Calculate total pages: (totalMovies + 9) / 10 * - Validate page number (1 to totalPages) * - Calculate start and end index * - Convert moviesCache.values() to List * - Loop from start to end and display: "ID: {id} | {title} ({year})" * * loadAllMovies() already has try-catch inside */ public void displayAllMovies(int page) { // TODO: Write your code here // loadAllMovies() already has try-catch // Your display logic here } /** * TODO 4 (BONUS): Display movie details by ID * * Steps: * - Call loadAllMovies() first * - Get movie from moviesCache using movieId * - If movie is null, print "Movie not found" * - Otherwise print: ID, Title, Year, Genres, Poster * * loadAllMovies() already has try-catch inside */ public void displayMovieDetails(Long movieId) { // TODO: Write your code here (BONUS) // loadAllMovies() already has try-catch // Your display logic here } private String getGenresString(List genres) { if (genres == null || genres.isEmpty()) { return "No genres"; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < genres.size(); i++) { sb.append(genres.get(i).getName()); if (i < genres.size() - 1) { sb.append(", "); } } return sb.toString(); } public int getTotalMovies() { return totalMovies; } }