import com.mathworks.mps.client.*;
import com.mathworks.mps.client.annotations.MWStructureList;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Future;

interface StudentSorter {
    @MWStructureList({Student.class})
    Student[] sortstudents(Student[] students) throws IOException, MATLABException;
}

//By default, MWClient is not interruptible. We need to change the configuration of the MWClient by extending MWClientDefaultConfig 
//and changing the isInterruptible method call to return true
class MyHttpClientConfig extends MWHttpClientDefaultConfig{
    public boolean isInterruptible() { return true; }
    public int getMaxConnectionsPerAddress() { return 10; }
} 

public class SortStudentsAsync {
    public static void main(String[] args) {
        try {
			// Create an interruptible MWHttpClient instance
            MWClient client = new MWHttpClient(new MyHttpClientConfig ());
			
			//Create an array of Student objects to pass as input arguments
            Student[] students = new Student[]{new Student("Toni Miller", 90, "A"),
                    new Student("Ed Plum", 80, "B+"),
                    new Student("Mark Jones", 85, "A-")};

			// Create the proxy object that represents sortstudents.ctf
            MWInvokable mwInvokable = client.createComponentProxy(new URL("http://localhost:9910/sortstudents"), new StudentMarshaller());
			// Create MWInvokeRequest object by passing the function name i.e., sortstudents and also the expected return type from the function execution
            MWInvokeRequest invokeRequest = new MWInvokeRequest("sortstudents", Student[].class);
			//Pass the input arguments to the function
            invokeRequest.setInputParams(new Object[]{students});

			//Make the request to the server
            MWRequest<Student[]> request = mwInvokable.invokeAsync(invokeRequest, null);
			//Poll on the future object till there is output
            Future<Student[]> f = request.getFuture();
            System.out.println("Student list sorted in the ascending order of scores : ");
            for (Student st : f.get()) {
                System.out.println(st);
            }

            client.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}
