Enhanced review process for PatchSet revisions

Adjusted the review mechanism for subsequent PatchSet revisions. Now,
only the differences between the two most recent revisions are sent to
ChatGPT, instead of the complete PatchSet.
When submitting a comment to ChatGPT, the entire PatchSet is still
provided as before.

Jira-Id: IT-103
Change-Id: I74f842a36510d46d243230f4110f5aa4a3b9df36
Signed-off-by: Patrizio <patrizio.gelosi@amarulasolutions.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
index cb45a74..381cd63 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/PatchSetReviewer.java
@@ -42,7 +42,7 @@
     public void review(Configuration config, String fullChangeId) throws Exception {
         reviewBatches = new ArrayList<>();
         commentProperties = gerritClient.getCommentProperties();
-        String patchSet = gerritClient.getPatchSet(fullChangeId);
+        String patchSet = gerritClient.getPatchSet(fullChangeId, isCommentEvent);
         if (patchSet.isEmpty()) {
             log.info("No file to review has been found in the PatchSet");
             return;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClient.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClient.java
index 0a51b31..5afda10 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClient.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClient.java
@@ -22,7 +22,11 @@
     }
 
     public String getPatchSet(String fullChangeId) throws Exception {
-        return gerritClientPatchSet.getPatchSet(fullChangeId);
+        return getPatchSet(fullChangeId, false);
+    }
+
+    public String getPatchSet(String fullChangeId, boolean isCommentEvent) throws Exception {
+        return gerritClientPatchSet.getPatchSet(fullChangeId, isCommentEvent);
     }
 
     public boolean isDisabledUser(String authorUsername) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientPatchSet.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientPatchSet.java
index 0bb5aa2..d4813e6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientPatchSet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/GerritClientPatchSet.java
@@ -37,9 +37,26 @@
         diffs = new ArrayList<>();
     }
 
-    private List<String> getAffectedFiles(String fullChangeId) throws Exception {
+    private int retrieveRevisionBase(String fullChangeId) throws Exception {
         URI uri = URI.create(config.getGerritAuthBaseUrl()
-                        + UriResourceLocator.gerritPatchSetFilesUri(fullChangeId));
+                + UriResourceLocator.gerritPatchSetRevisionsUri(fullChangeId));
+        log.debug("Retrieve Revision URI: '{}'", uri);
+        JsonObject reviews = forwardGetRequestReturnJsonObject(uri);
+        try {
+            Set<String> revisions = reviews.get("revisions").getAsJsonObject().keySet();
+            return revisions.size() -1;
+        }
+        catch (Exception e) {
+            log.error("Could not retrieve revisions for PatchSet with fullChangeId: {}", fullChangeId, e);
+            throw e;
+        }
+    }
+
+    private List<String> getAffectedFiles(String fullChangeId, int revisionBase) throws Exception {
+        URI uri = URI.create(config.getGerritAuthBaseUrl()
+                + UriResourceLocator.gerritPatchSetFilesUri(fullChangeId)
+                + UriResourceLocator.gerritRevisionBasePostfixUri(revisionBase));
+        log.debug("Affected Files URI: '{}'", uri);
         JsonObject affectedFileMap = forwardGetRequestReturnJsonObject(uri);
         List<String> files = new ArrayList<>();
         for (Map.Entry<String, JsonElement> file : affectedFileMap.entrySet()) {
@@ -115,7 +132,7 @@
         diffs.add(gson.toJson(outputFileDiff));
     }
 
-    private String getFileDiffsJson(String fullChangeId, List<String> files) throws Exception {
+    private String getFileDiffsJson(String fullChangeId, List<String> files, int revisionBase) throws Exception {
         List<String> enabledFileExtensions = config.getEnabledFileExtensions();
         for (String filename : files) {
             isCommitMessage = filename.equals("/COMMIT_MSG");
@@ -125,18 +142,23 @@
             }
             URI uri = URI.create(config.getGerritAuthBaseUrl()
                     + UriResourceLocator.gerritPatchSetFilesUri(fullChangeId)
-                    + UriResourceLocator.gerritDiffPostfixUri(filename));
+                    + UriResourceLocator.gerritDiffPostfixUri(filename)
+                    + UriResourceLocator.gerritRevisionBasePostfixUri(revisionBase));
+            log.debug("getFileDiffsJson URI: '{}'", uri);
             String fileDiffJson = forwardGetRequest(uri).replaceAll("^[')\\]}]+", "");
             processFileDiff(filename, fileDiffJson);
         }
         return "[" + String.join(",", diffs) + "]\n";
     }
 
-    public String getPatchSet(String fullChangeId) throws Exception {
-        List<String> files = getAffectedFiles(fullChangeId);
+    public String getPatchSet(String fullChangeId, boolean isCommentEvent) throws Exception {
+        int revisionBase = isCommentEvent ? 0 : retrieveRevisionBase(fullChangeId);
+        log.debug("Revision base: {}", revisionBase);
+
+        List<String> files = getAffectedFiles(fullChangeId, revisionBase);
         log.debug("Patch files: {}", files);
 
-        String fileDiffsJson = getFileDiffsJson(fullChangeId, files);
+        String fileDiffsJson = getFileDiffsJson(fullChangeId, files, revisionBase);
         log.debug("File diffs: {}", fileDiffsJson);
 
         return fileDiffsJson;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/UriResourceLocator.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/UriResourceLocator.java
index c3222ce..6eeb28c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/UriResourceLocator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/client/UriResourceLocator.java
@@ -11,8 +11,8 @@
         throw new IllegalStateException("Utility class");
     }
 
-    private static String gerritSetChangesUri(String fullChangeId, String resourcePath) {
-        return AUTH_PREFIX_URI + "/changes/" + fullChangeId + resourcePath;
+    private static String gerritSetChangesUri(String fullChangeId, String uriPostfix) {
+        return AUTH_PREFIX_URI + "/changes/" + fullChangeId + uriPostfix;
     }
 
     public static String gerritAccountsUri() {
@@ -27,10 +27,18 @@
         return "/" + accountId + "/groups";
     }
 
+    public static String gerritRevisionBasePostfixUri(int revisionBase) {
+        return revisionBase > 0 ? "/?base=" + revisionBase : "";
+    }
+
     public static String gerritDiffPostfixUri(String filename) {
         return "/" + URLEncoder.encode(filename, StandardCharsets.UTF_8) + "/diff";
     }
 
+    public static String gerritPatchSetRevisionsUri(String fullChangeId) {
+        return gerritSetChangesUri(fullChangeId, "/?o=ALL_REVISIONS");
+    }
+
     public static String gerritPatchSetFilesUri(String fullChangeId) {
         return gerritSetChangesUri(fullChangeId, "/revisions/current/files");
     }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
index bf2553f..699775a 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTest.java
@@ -146,6 +146,13 @@
                         .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
                         .withBodyFile("gerritAccountGroups.json")));
 
+        // Mock the behavior of the gerritPatchSetRevisionsUri request
+        WireMock.stubFor(WireMock.get(gerritPatchSetRevisionsUri(fullChangeId))
+                .willReturn(WireMock.aResponse()
+                        .withStatus(HTTP_OK)
+                        .withHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())
+                        .withBody("{\"revisions\":{\"aa5be5ebb80846475ec4dfe43e0799eb73c6415a\":{}}}")));
+
         // Mock the behavior of the gerritPatchSetFiles request
         WireMock.stubFor(WireMock.get(gerritPatchSetFilesUri(fullChangeId))
                 .willReturn(WireMock.aResponse()