package movie.apis; import com.google.gson.*; import com.google.gson.reflect.TypeToken; import java.io.IOException; import java.net.HttpURLConnection; 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; public class MovieService { private final static String GENRES_URL = "https://api.meshcomp.ir/api/v1/genres"; private final static String MOVIE_BY_ID_URL = "https://api.meshcomp.ir/api/v1/movies/"; private final static HttpClient client = HttpClient.newHttpClient(); 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()); } } /** * 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) { try { String RawData = getMoviesByGenreList(genreId, page); if (RawData == null) throw new IllegalArgumentException("Invalid genreId or page number; no data found"); JsonObject JsonData = JsonParser.parseString(RawData).getAsJsonObject(); JsonArray MoviesArray = JsonData.getAsJsonArray("movies"); Type MovieListType = new TypeToken>(){}.getType(); Gson GsonHandle = new Gson(); List Movies = GsonHandle.fromJson(MoviesArray, MovieListType); System.out.printf("\nMovies with %s genre:\n", JsonData.getAsJsonObject("genre").get("name").getAsString()); for (Movie CurrentMovie : Movies) System.out.printf("ID: %d | %s (%s)\n", CurrentMovie.getId(), CurrentMovie.getTitle(), CurrentMovie.getYear()); System.out.printf("\nTotal: %s - Total pages: %s", JsonData.get("total").getAsString(), JsonData.get("total_pages").getAsString()); System.out.println(); } catch (Exception e) { System.err.println("ERROR: " + e.getMessage()); } } /** * BONUS: Fetch movie details from API using movie ID * URL format: https://api.meshcomp.ir/api/v1/movies/{movieId} */ private String getMovieById(Long movieId) { try { final String URL = MOVIE_BY_ID_URL + movieId; HttpRequest Request = HttpRequest.newBuilder().uri(URI.create(URL)).build(); HttpResponse Respone = client.send(Request, HttpResponse.BodyHandlers.ofString()); if (Respone.statusCode() == HttpURLConnection.HTTP_OK) return Respone.body(); return null; } catch (Exception e) { System.out.println("!!Exception : " + e.getMessage()); } return null; } /** * BONUS TODO: Display complete movie details for a given movie ID * * Expected JSON format from getMovieById(): * { * "id": 1, * "title": "The Shawshank Redemption", * "year": "1994", * "genres": ["Crime", "Drama"], * "poster": "https://moviesapi.ir/images/tt0111161_poster.jpg", * "country": "USA", * "imdb_rating": "9.3" * } * * INSTRUCTIONS: * 1. Call getMovieById(movieId) to get the JSON response * 2. Check if response is null (if yes, print error and return) * 3. Parse the JSON string to JsonObject (inside try-catch) * 4. Extract all fields: id, title, year, genres array, poster, country, imdb_rating * 5. Convert genres array to comma-separated string * 6. Print all movie details in a readable format * * PUT ALL PARSING CODE INSIDE THE EXISTING try-catch * * @param movieId The ID of the movie to display */ public void displayMovieDetails(Long movieId) { String jsonResponse = getMovieById(movieId); if (jsonResponse == null) { System.out.println("Failed to get movie details for ID: " + movieId); return; } try { JsonObject JsonData = JsonParser.parseString(jsonResponse).getAsJsonObject(); Gson GsonHandle = new Gson(); Type MovieType = new TypeToken(){}.getType(); Movie RequestedMovie = GsonHandle.fromJson(JsonData, MovieType); System.out.println(); System.out.println(RequestedMovie); } catch (Exception e) { System.err.println("ERROR parsing movie details: " + e.getMessage()); } } }