package com.endercrest.uwaterlooapi.data;

import com.google.gson.*;
import com.google.gson.annotations.Expose;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Created by Thomas Cordua-von Specht on 11/23/2016.
 */
public class ApiRequest<T> {

    @Expose
    private Meta meta;
    @Expose
    private T data;

    /**
     * Get the meta data of the ApiRequest sent with every api call.
     * @return {@link Meta}
     */
    public Meta getMeta() {
        return meta;
    }

    /**
     * Get the data of the ApiRequest.
     * @return Returns the type of the original request.
     */
    public T getData() {
        return data;
    }

    /**
     * Creates a new API Request with the requested endpoint using the apiKey, which then uses
     * the apiRequestType to construct the object correctly.
     *
     * Examples:
     * createApiRequest("courses", "123456", new TypeToken<ApiRequest<List<CourseMinimal>>>() {}.getType())
     *
     * @param endpoint The endpoint of the university v2 api.
     * @param apiKey Your apiKey given by the university of waterloo.
     * @param apiRequestType references the structure of the ApiRequest. IE {@link TypeToken}
     * @param <Z> The model of the data.
     * @return A Parsed ApiRequest with the type structure given above.
     */
    public static <Z> ApiRequest<Z> createApiRequest(String endpoint, String apiKey, Type apiRequestType) {
        return createApiRequest(endpoint, apiKey, "", apiRequestType);
    }

    /**
     * Creates a new API Request with the requested endpoint using the apiKey, which then uses
     * the apiRequestType to construct the object correctly with parameters.
     *
     * Examples:
     * createApiRequest("courses", "123456", new TypeToken<ApiRequest<List<CourseMinimal>>>() {}.getType())
     *
     * @param endpoint The endpoint of the university v2 api.
     * @param apiKey Your apiKey given by the university of waterloo.
     * @param params Any extra parameters that the path might accept.
     * @param apiRequestType references the structure of the ApiRequest. IE {@link TypeToken}
     * @param <Z> The model of the data.
     * @return A Parsed ApiRequest with the type structure given above.
     */
    public static <Z> ApiRequest<Z> createApiRequest(String endpoint, String apiKey, String params, Type apiRequestType){
        Gson gson = new GsonBuilder().create();

        String json = "";
        try {
            URL url = new URL(String.format("https://api.uwaterloo.ca/v2/%s.json?key=%s%s", endpoint, apiKey, params.equals("") ? "": "&"+params));
            URLDownload download = new URLDownload(url);
            json = download.downloadContents();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return gson.fromJson(json, apiRequestType);
    }

}

@@ -924,32 +924,37 @@
 orrectly.%0A     *
+ %3Cbr%3E
 %0A     * Examples
@@ -946,32 +946,36 @@
      * Examples:
+%3Cbr%3E
 %0A     * createAp
@@ -983,35 +983,55 @@
 Request(
-%22
+&quot;
 courses
-%22, %22123456%22
+&quot;, &quot;123456&quot;
 , new Ty
@@ -1029,33 +1029,36 @@
 ;, new TypeToken
-%3C
+&lt;
 ApiRequest%3CList%3C
@@ -1043,38 +1043,44 @@
 en&lt;ApiRequest
-%3CList%3C
+&lt;List&lt;
 CourseMinimal%3E%3E%3E
@@ -1068,35 +1068,44 @@
 lt;CourseMinimal
-%3E%3E%3E
+&gt;&gt;&gt;
 () %7B%7D.getType())
@@ -1827,24 +1827,29 @@
 ters.%0A     *
+ %3Cbr%3E
 %0A     * Exam
@@ -1853,16 +1853,20 @@
 xamples:
+%3Cbr%3E
 %0A     * 
@@ -1886,27 +1886,69 @@
 est(
-%22
+&quot;
 courses
-%22, %22123456%22
+&quot;, &quot;123456&quot;, &quot;term=123&quot;
 , ne
@@ -1958,17 +1958,20 @@
 ypeToken
-%3C
+&lt;
 ApiReque
@@ -1976,14 +1976,20 @@
 uest
-%3CList%3C
+&lt;List&lt;
 Cour
@@ -2001,11 +2001,20 @@
 imal
-%3E%3E%3E
+&gt;&gt;&gt;
 () %7B

Fix Javadoc Formatting.