/*
 * Copyright 2012-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package com.facebook.buck.util;

import com.google.common.base.Charsets;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

/**
 * HTTP POST things to a commonly used endpoint.
 */
public class HttpEndpoint {

  private final static int DEFAULT_COMMON_TIMEOUT_MS = 5000;

  private URL url;
  private int timeout = DEFAULT_COMMON_TIMEOUT_MS;

  public HttpEndpoint(String url) {
    try {
      this.url = new URL(url);
    } catch (MalformedURLException e) {
      throw new HumanReadableException(e.getMessage());
    }
  }

  public InputStream post(Map<String,Object> params) {
    return post(encodeParameters(params));
  }

  public InputStream post(String content) {
    HttpURLConnection connection = buildConnection("POST");
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    return send(connection, content);
  }

  private InputStream send(HttpURLConnection connection, String content) {
    try {
      DataOutputStream out = new DataOutputStream(connection.getOutputStream());
      out.writeBytes(content);
      out.flush();
      out.close();
      return connection.getInputStream();
    } catch (IOException e) {
      throw new HumanReadableException(
          "Error sending and receiving data to %s: %s",
          url,
          e.getMessage());
    }
  }

  private HttpURLConnection buildConnection(String httpMethod) {
    try {
      HttpURLConnection connection = (HttpURLConnection) this.url.openConnection();
      connection.setUseCaches(false);
      connection.setDoOutput(true);
      connection.setConnectTimeout(timeout);
      connection.setReadTimeout(timeout);
      connection.setRequestMethod(httpMethod);
      return connection;
    } catch (IOException e) {
      throw new HumanReadableException("Unable to open connection to %s", this.url);
    }
  }

  private static String encodeParameters(Map<String,Object> params) {
    String content = "";
    for (Object key : params.keySet()) {
      Object value = params.get(key);
      try {
        String ukey = URLEncoder.encode((String) key, String.valueOf(Charsets.UTF_8));
        String uvalue = URLEncoder.encode(String.valueOf(value), String.valueOf(Charsets.UTF_8));
        content += ukey + "=" + uvalue + "&";
      } catch (UnsupportedEncodingException e) {
        throw new HumanReadableException("Unable to URL encode '%s': %s", key, value);
      }
    }
    return content.substring(0, content.length()-1);
  }

  public void setTimeout(int timeout) {
    this.timeout = timeout;
  }
}

@@ -846,47 +846,8 @@
 on;%0A
-import java.net.MalformedURLException;%0A
 impo
@@ -1007,27 +1007,26 @@
 %0A  p
-rivate final static
+ublic static final
  int
@@ -1170,152 +1170,57 @@
 rl) 
-%7B%0A    try %7B%0A      this.url = new URL(url);%0A    %7D catch (MalformedURLException e) %7B%0A      throw new HumanReadableException(e.getMessage());%0A    %7D
+throws IOException %7B%0A    this.url = new URL(url);
 %0A  %7D
@@ -1269,24 +1269,43 @@
 ect%3E params)
+ throws IOException
  %7B%0A    retur
@@ -1380,24 +1380,43 @@
 ing content)
+ throws IOException
  %7B%0A    HttpU
@@ -1670,30 +1670,37 @@
 ontent) 
-%7B%0A    try
+throws IOException
  %7B%0A
-  
     Data
@@ -1770,26 +1770,24 @@
 eam());%0A    
-  
 out.writeByt
@@ -1799,26 +1799,24 @@
 ntent);%0A    
-  
 out.flush();
@@ -1812,26 +1812,24 @@
 ut.flush();%0A
-  
     out.clos
@@ -1833,26 +1833,24 @@
 lose();%0A    
-  
 return conne
@@ -1877,182 +1877,8 @@
 ();%0A
-    %7D catch (IOException e) %7B%0A      throw new HumanReadableException(%0A          %22Error sending and receiving data to %25s: %25s%22,%0A          url,%0A          e.getMessage());%0A    %7D%0A
   %7D%0A
@@ -1945,22 +1945,29 @@
 od) 
-%7B%0A    try
+throws IOException
  %7B%0A
-  
     
@@ -2044,26 +2044,24 @@
 tion();%0A    
-  
 connection.s
@@ -2076,34 +2076,32 @@
 hes(false);%0A    
-  
 connection.setDo
@@ -2114,26 +2114,24 @@
 (true);%0A    
- 
- 
 connection.s
@@ -2149,34 +2149,32 @@
 meout(timeout);%0A
-  
     connection.s
@@ -2201,18 +2201,16 @@
 t);%0A    
-  
 connecti
@@ -2246,18 +2246,16 @@
 d);%0A    
- 
- 
 return c
@@ -2269,129 +2269,8 @@
 on;%0A
-    %7D catch (IOException e) %7B%0A      throw new HumanReadableException(%22Unable to open connection to %25s%22, this.url);%0A    %7D%0A
   %7D%0A
@@ -2337,16 +2337,58 @@
  params)
+%0A      throws UnsupportedEncodingException
  %7B%0A    S
@@ -2490,22 +2490,8 @@
 y);%0A
-      try %7B%0A  
     
@@ -2573,26 +2573,24 @@
 _8));%0A      
-  
 String uvalu
@@ -2673,18 +2673,16 @@
 ;%0A      
-  
 content 
@@ -2715,152 +2715,8 @@
 &%22;%0A
-      %7D catch (UnsupportedEncodingException e) %7B%0A        throw new HumanReadableException(%22Unable to URL encode '%25s': %25s%22, key, value);%0A      %7D%0A
     

Change HttpEndpoint to throw checked exceptions.