package edu.washington.escience.myria.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

/**
 * Util methods for handling of Json API stuff.
 * */
public final class JsonAPIUtils {

  /**
   * Util class allows no instance.
   * */
  private JsonAPIUtils() {
  }

  /**
   * @param masterHostname master hostname
   * @param apiPort rest api port
   * @param queryFile query file
   * @return a HTTPURLConnection instance of retrieving responses.
   * @throws IOException if IO errors
   * */
  public static HttpURLConnection submitQuery(final String masterHostname, final int apiPort, final File queryFile)
      throws IOException {
    return submitQuery(masterHostname, apiPort, FileUtils.readFileToString(queryFile));
  }

  /**
   * @param masterHostname master hostname
   * @param apiPort rest api port
   * @param queryString query string
   * @return a HTTPURLConnection instance of retrieving responses.
   * @throws IOException if IO errors
   * */
  public static HttpURLConnection submitQuery(final String masterHostname, final int apiPort, final String queryString)
      throws IOException {
    String type = "application/json";
    URL u = new URL("http://" + masterHostname + ":" + apiPort + "/query");
    HttpURLConnection conn = (HttpURLConnection) u.openConnection();
    conn.setDoOutput(true);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", type);
    byte[] e = queryString.getBytes();
    conn.setRequestProperty("Content-Length", String.valueOf(e.length));
    OutputStream os = conn.getOutputStream();
    os.write(e);
    os.close();
    conn.connect();
    conn.getResponseCode();
    return conn;
  }

  /**
   * Construct a URL for get/put of a dataset.
   * 
   * @param host master hostname
   * @param port master port
   * @param user user parameter of the dataset
   * @param program program parameter of the dataset
   * @param relation relation parameter of the dataset
   * @param format the format of the relation ("json", "csv", "tsv")
   * @return a URL for the dataset
   * @throws IOException if an error occurs
   */
  private static URL getDatasetUrl(final String host, final int port, final String user, final String program,
      final String relation, final String format) throws IOException {
    return new URL(String.format("http://%s:%d/dataset/user-%s/program-%s/relation-%s/data?format=%s", host, port,
        user, program, relation, format));
  }

  /**
   * Download a dataset.
   * 
   * @param host master hostname
   * @param port master port
   * @param user user parameter of the dataset
   * @param program program parameter of the dataset
   * @param relation relation parameter of the dataset
   * @param format the format of the relation ("json", "csv", "tsv")
   * 
   * @return dataset encoded in the requested format
   * @throws IOException if an error occurs
   */
  public static String download(final String host, final int port, final String user, final String program,
      final String relation, final String format) throws IOException {
    URL url = getDatasetUrl(host, port, user, program, relation, format);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setDoOutput(true);
    conn.setRequestMethod("GET");

    if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
      throw new IOException("Failed to download result:" + conn.getResponseCode());
    }

    try {
      InputStream is = conn.getInputStream();
      return IOUtils.toString(is, "UTF-8");
    } finally {
      conn.disconnect();
    }
  }

  /**
   * Replace the contents of a dataset.
   * 
   * @param host master hostname
   * @param port master port
   * @param user user parameter of the dataset
   * @param program program parameter of the dataset
   * @param relation relation parameter of the dataset
   * @param dataset the dataset to upload
   * @param format the format of the relation ("json", "csv", "tsv")
   * 
   * @throws IOException if an error occurs
   */
  public static void replace(final String host, final int port, final String user, final String program,
      final String relation, final String dataset, final String format) throws IOException {
    URL url = getDatasetUrl(host, port, user, program, relation, format);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setDoOutput(true);
    conn.setRequestProperty("Content-Type", "application/octet-stream");
    conn.setRequestMethod("PUT");

    byte[] payload = format.getBytes("UTF-8");
    conn.setFixedLengthStreamingMode(payload.length);
    try {
      OutputStream out = conn.getOutputStream();
      out.write(payload);
      if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
        throw new IOException("Failed upload: " + conn.getResponseCode());
      }
    } finally {
      conn.disconnect();
    }
  }

  /**
   * @param masterHostname master hostname
   * @param apiPort rest api port
   * @param queryFile query file
   * @return a HTTPURLConnection instance of retrieving responses.
   * @throws IOException if IO errors
   * */
  public static HttpURLConnection ingestData(final String masterHostname, final int apiPort, final File queryFile)
      throws IOException {
    return ingestData(masterHostname, apiPort, FileUtils.readFileToString(queryFile));
  }

  /**
   * @param masterHostname master hostname
   * @param apiPort rest api port
   * @param queryString query string
   * @return a HTTPURLConnection instance of retrieving responses.
   * @throws IOException if IO errors
   * */
  public static HttpURLConnection ingestData(final String masterHostname, final int apiPort, final String queryString)
      throws IOException {

    String type = "application/json";
    URL u = new URL("http://" + masterHostname + ":" + apiPort + "/dataset");
    HttpURLConnection conn = (HttpURLConnection) u.openConnection();
    conn.setDoOutput(true);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", type);
    byte[] e = queryString.getBytes();
    conn.setRequestProperty("Content-Length", String.valueOf(e.length));
    OutputStream os = conn.getOutputStream();
    os.write(e);
    os.close();
    conn.connect();
    conn.getResponseCode();
    return conn;
  }
}

@@ -4694,21 +4694,22 @@
 yload = 
-forma
+datase
 t.getByt

Fix source of payload bytes