package org.helioviewer.jhv.io;

import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Callable;

import javax.annotation.Nonnull;

import org.helioviewer.jhv.Log;
import org.helioviewer.jhv.gui.Message;
import org.helioviewer.jhv.threads.EventQueueCallbackExecutor;
import org.json.JSONArray;

import com.google.common.util.concurrent.FutureCallback;

public class TAPClient {

    public interface Receiver {
        void setResponse(JSONArray ja);
    }

    public static void submitQuery(@Nonnull Receiver receiver, @Nonnull String serverUrl, @Nonnull String adql) {
        EventQueueCallbackExecutor.pool.submit(new ADQLQuery(serverUrl, adql), new Callback(receiver));
    }

    private record ADQLQuery(String serverUrl, String adql) implements Callable<JSONArray> {
        @Override
        public JSONArray call() throws Exception {
            URI uri = new URI(serverUrl + "/sync?REQUEST=doQuery&LANG=ADQL&FORMAT=json&QUERY=" + URLEncoder.encode(adql, StandardCharsets.UTF_8));
            return JSONUtils.get(uri).getJSONArray("data");
        }
    }

    private record Callback(Receiver receiver) implements FutureCallback<JSONArray> {

        @Override
        public void onSuccess(JSONArray result) {
            receiver.setResponse(result);
        }

        @Override
        public void onFailure(@Nonnull Throwable t) {
            Log.error(t);
            Message.err("An error occurred while querying the server:", t.getMessage(), false);
        }

    }

}

@@ -154,16 +154,52 @@
 allable;
+%0Aimport java.util.function.Function;
 %0A%0Aimport
@@ -521,16 +521,19 @@
 void set
+TAP
 Response
@@ -537,20 +537,16 @@
 nse(
-JSONArray ja
+Object o
 );%0A 
@@ -661,16 +661,50 @@
 ing adql
+, Function%3CObject, JSONArray%3E func
 ) %7B%0A    
@@ -775,16 +775,22 @@
 rl, adql
+, func
 ), new C
@@ -874,16 +874,79 @@
 ing adql
+,%0A                             Function%3CObject, JSONArray%3E func
 ) implem
@@ -959,25 +959,22 @@
 allable%3C
-JSONArray
+Object
 %3E %7B%0A    
@@ -1201,14 +1201,22 @@
     
-return
+JSONArray ja =
  JSO
@@ -1253,16 +1253,51 @@
 data%22);%0A
+            return func.apply(ja);%0A
         
@@ -1378,25 +1378,22 @@
 allback%3C
-JSONArray
+Object
 %3E %7B%0A%0A   
@@ -1437,25 +1437,22 @@
 Success(
-JSONArray
+Object
  result)
@@ -1478,16 +1478,19 @@
 iver.set
+TAP
 Response

Allow transforming the result in TAP thread