package edu.pdx.cs410J.web;

import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.io.*;
import java.nio.charset.Charset;

/**
 * A helper class that provides methods for requesting resources via HTTP
 */
public class HttpRequestHelper {
  /**
   * Performs an HTTP GET on the given URL
   *
   * @param urlString The URL to get
   * @param parameters The key/value query parameters
   * @return A <code>Response</code> summarizing the result of the GET
   */
  protected Response get(String urlString, String... parameters) throws IOException {
    checkParameters(parameters);

    StringBuilder query = encodeParameters(parameters);
    if (query.length() > 0) {
      query.insert(0, '?');
    }

    URL url = new URL(urlString + query);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setDoOutput(true);
    conn.setDoInput(true);

    return new Response(conn);

  }

  /**
   * Performs an HTTP POST to the given URL
   * @param urlString The URL to post to
   * @param parameters The key/value parameters
   * @return A <code>Response</code> summarizing the result of the POST
   */
  protected Response post(String urlString, String... parameters) throws IOException {
    checkParameters(parameters);

    StringBuilder data = encodeParameters(parameters);

    URL url = new URL(urlString);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setDoOutput(true);

    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream(), Charset.forName("UTF-8"));
    wr.write(data.toString());
    wr.flush();

    Response response = new Response(conn);
    wr.close();

    return response;

  }

  /**
   * Encodes parameters to be sent to the server via an HTTP GET, POST, or DELETE
   * @param parameters The parameter key/value pairs
   * @return The encoded parameters
   * @throws java.io.UnsupportedEncodingException If we can't encode UTF-8
   */
  private StringBuilder encodeParameters(String... parameters) throws UnsupportedEncodingException {
    StringBuilder query = new StringBuilder();
    for (int i = 0; i < parameters.length; i += 2) {
      String key = parameters[i];
      String value = parameters[i + 1];
      query.append(URLEncoder.encode(key, "UTF-8"));
      query.append("=");
      query.append(URLEncoder.encode(value, "UTF-8"));
      if (i < parameters.length - 2) {
        query.append("&");
      }
    }
    return query;
  }

  private void checkParameters(String... parameters) {
    if (parameters.length % 2 != 0) {
      String s = "You must specify an even number of parameters (key/value pairs)";
      throw new IllegalArgumentException(s);
    }
  }

  /**
   * Performs an HTTP PUT on the given URL
   *
   * @param urlString The URL to put to
   * @param parameters key/value parameters to the put
   * @return A <code>Reponse</code> summarizing the result of the PUT
   */
  protected Response put(String urlString, String... parameters) throws IOException {
    checkParameters(parameters);

    StringBuilder data = new StringBuilder();
    for (int i = 0; i < parameters.length; i += 2) {
      String key = parameters[i];
      String value = parameters[i + 1];
      data.append(key);
      data.append("=");
      data.append(value);
      data.append("\n");
    }

    URL url = new URL(urlString);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("PUT");
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setRequestProperty("Content-Type", "text/plain");
    conn.setRequestProperty("Context-Length", String.valueOf(data.length()));

    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream(), Charset.forName("UTF-8"));
    wr.write(data.toString());
    wr.flush();

    Response response = new Response(conn);
    wr.close();

    return response;
  }

  /**
   * Encapsulates a response to an HTTP request
   */
  public static class Response {

    private final int code;

    private final String content;

    private int contentLines = 0;

    private Response(HttpURLConnection conn) throws IOException {
      this.code = conn.getResponseCode();
      if (this.code != java.net.HttpURLConnection.HTTP_OK) {
        this.content = conn.getResponseMessage();
        return;
      }

      StringBuilder content = new StringBuilder();
      BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
      String line;
      while ((line = rd.readLine()) != null) {
        content.append(line);
        content.append("\n");
        contentLines++;
      }
      rd.close();

      this.content = content.toString().trim();
    }

    /**
     * Returns the HTTP status code of the response
     * @see java.net.HttpURLConnection#getResponseCode()
     */
    public int getCode() {
      return code;
    }

    /**
     * Returns the (presumably textual) response from the URL
     * @return
     */
    public String getContent() {
      return content;
    }

    /**
     * Returns the number of lines in the response's content
     */
    public int getContentLines() {
      return contentLines;
    }
  }

  /**
   * A main method that requests a resource from a URL using a given HTTP method
   */
  public static void main(String[] args) throws IOException {
    String method = args[0];
    String url = args[1];
    String[] parameters = new String[args.length - 2];
    System.arraycopy(args, 2, parameters, 0, parameters.length);

    HttpRequestHelper helper = new HttpRequestHelper();

    Response response;
    if (method.equalsIgnoreCase("PUT")) {
      response = helper.put(url, parameters);

    } else if (method.equalsIgnoreCase("GET")) {
      response = helper.get(url, parameters);

    } else if (method.equalsIgnoreCase("POST")) {
      response = helper.post(url, parameters);

    } else {
      System.err.println("** Unknown method: " + method);
      return;
    }

    System.out.println("Returned code " + response.getCode() + " and " +
      response.getContentLines() + " lines of content\n");
    System.out.println(response.getContent());

  }
}

@@ -1272,32 +1272,599 @@
 s IOException %7B%0A
+    return sendEncodedRequest(urlString, %22POST%22, parameters);%0A%0A  %7D%0A%0A  /**%0A   * Performs an HTTP DELETE to the given URL%0A   * @param urlString The URL to post to%0A   * @param parameters The key/value parameters%0A   * @return A %3Ccode%3EResponse%3C/code%3E summarizing the result of the POST%0A   */%0A  protected Response delete(String urlString, String... parameters) throws IOException %7B%0A    return sendEncodedRequest(urlString, %22DELETE%22, parameters);%0A%0A  %7D%0A%0A  private Response sendEncodedRequest(String urlString, String requestMethod, String... parameters) throws IOException %7B%0A
     checkParamet
@@ -1872,32 +1872,32 @@
 rs(parameters);%0A
-
 %0A    StringBuild
@@ -2068,22 +2068,29 @@
 tMethod(
-%22POST%22
+requestMethod
 );%0A    c
@@ -2316,32 +2316,32 @@
    wr.close();%0A%0A
+
     return respo
@@ -2345,17 +2345,16 @@
 sponse;%0A
-%0A
   %7D%0A%0A  /

Add a helper method to send an HTTP DELETE request.