/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060131   125777 jesper@selskabet.org - Jesper S Moller
 *******************************************************************************/
package org.eclipse.wst.ws.internal.explorer.platform.wsdl.transport;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Hashtable;
import javax.net.ssl.SSLSocketFactory;
import org.eclipse.wst.ws.internal.explorer.platform.util.XMLUtils;
import org.w3c.dom.Element;
import sun.misc.BASE64Encoder;

public class HTTPTransport
{
  private final String SYS_PROP_HTTPS_PROXY_HOST = "https.proxyHost";
  private final String SYS_PROP_HTTPS_PROXY_PORT = "https.proxyPort";
  private final String SYS_PROP_HTTP_PROXY_HOST = "http.proxyHost";
  private final String SYS_PROP_HTTP_PROXY_PORT = "http.proxyPort";
  private final String SYS_PROP_HTTP_PROXY_USER_NAME = "http.proxyUserName";
  private final String SYS_PROP_HTTP_PROXY_PASSWORD = "http.proxyPassword";

  private final String HTTP_METHOD = "POST";
  private final String HTTP_VERSION = "HTTP/1.1";
  private final String HTTP_HEADER_SOAP_ACTION = "SOAPAction";
  public static final String HTTP_HEADER_AUTH = "Authorization";
  public static final String HTTP_HEADER_WWW_AUTH = "WWW-Authenticate";
  private final String HTTP_HEADER_PROXY_AUTH = "Proxy-authorization";
  private final String HTTP_HEADER_COOKIE = "Cookie";
  private final String HTTP_HEADER_COOKIE2 = "Cookie2";
  private final String HTTP_HEADER_HOST = "Host";
  private final String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
  public static final String HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
  private final String HTTP_HEADER_ACCEPT = "Accept";
  private final String HTTP_HEADER_USER_AGENT = "User-Agent";
  private final String HTTP_HEADER_CACHE_CONTROL = "Cache-Control";
  private final String HTTP_HEADER_PRAGMA = "Pragma";
  private final String HTTP_HEADER_TRANSFER_ENCODEING = "Transfer-Encoding";
  private final String HTTP_HEADER_CONNECTION = "Connection";
  
  private final int HTTP_CODE_CONTINUE = 100;
  //private final int HTTP_CODE_OK = 200;
  private final int HTTP_CODE_EXCEPTION = 300;

  private final String IBM_WEB_SERVICES_EXPLORER = "IBM Web Services Explorer";
  private final String TEXT_XML = "text/xml";
  private final String CONTENT_TYPE_VALUE = "text/xml; charset=utf-8";
  private final String ACCEPT_VALUE = "application/soap+xml, application/dime, multipart/related, text/*";
  public static final String BASIC = "Basic";
  private final String NO_CACHE = "no-cache";
  private final String CHUNKED = "chunked";
  private final String CLOSE = "close";
  private final String HTTPS = "https";
  private final char QUOTE = '\"';
  public static final char COLON = ':';
  private final char SPACE = ' ';
  private final char TAB = '\t';
  private final char R = '\r';
  private final char N = '\n';
  private final char ROOT = '/';
  private final String NEW_LINE = "\r\n";
  private final String EMPTY_STRING = "";

  private final int DEFAULT_HTTP_PORT = 80;
  private final int DEFAULT_HTTPS_PORT = 443;
  private final String DEFAULT_SOAP_ENCODING = "UTF-8";
  private final String DEFAULT_HTTP_HEADER_ENCODING = "iso-8859-1";

  private String httpBasicAuthUsername;
  private String httpBasicAuthPassword;
  private boolean maintainSession = false;
  private String cookie;
  private String cookie2;
  private HTTPResponse httpResponse;

  public String getHttpBasicAuthUsername()
  {
    return httpBasicAuthUsername;
  }
  
  public void setHttpBasicAuthUsername(String httpBasicAuthUsername)
  {
    this.httpBasicAuthUsername = httpBasicAuthUsername;
  }
  
  public String getHttpBasicAuthPassword()
  {
    return httpBasicAuthPassword;
  }
  
  public void setHttpBasicAuthPassword(String httpBasicAuthPassword)
  {
    this.httpBasicAuthPassword = httpBasicAuthPassword;
  }

  private String getMethod(URL url)
  {
    StringBuffer sb = new StringBuffer(HTTP_METHOD);
    sb.append(SPACE);
    String protocol = url.getProtocol();
    String httpProxyHost = System.getProperty(SYS_PROP_HTTP_PROXY_HOST);
    String httpsProxyHost = System.getProperty(SYS_PROP_HTTPS_PROXY_HOST);
    if (protocol.equalsIgnoreCase("http") && httpProxyHost != null && httpProxyHost.length() > 0)
    {
      sb.append(url.toString());
    }
    else if (protocol.equalsIgnoreCase("https") && httpsProxyHost != null && httpsProxyHost.length() > 0)
    {
      sb.append(url.toString());
    }
    else
    {
      String file = url.getFile();
      if (file != null && file.length() > 0)
        sb.append(file);
      else
        sb.append(ROOT);
    }
    sb.append(SPACE);
    sb.append(HTTP_VERSION);
    sb.append(NEW_LINE);
    return sb.toString();
  }

  private String getHost(URL url)
  {
    StringBuffer sb = new StringBuffer(HTTP_HEADER_HOST);
    sb.append(COLON);
    sb.append(SPACE);
    sb.append(url.getHost());
    sb.append(COLON);
    int port = url.getPort();
    if (port > 0)
      sb.append(String.valueOf(port));
    else if (url.getProtocol().equalsIgnoreCase(HTTPS))
      sb.append(DEFAULT_HTTPS_PORT);
    else
      sb.append(DEFAULT_HTTP_PORT);
    sb.append(NEW_LINE);
    return sb.toString();
  }
  
  private String getContentType()
  {
    return getHTTPHeader(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_VALUE);
  }
  
  private String getContentLength(String payload)
  {
    return getHTTPHeader(HTTP_HEADER_CONTENT_LENGTH, String.valueOf(payload.length()));
  }

  private String getSOAPAction(String soapAction)
  {
    StringBuffer sb = new StringBuffer(HTTP_HEADER_SOAP_ACTION);
    sb.append(COLON);
    sb.append(SPACE);
    sb.append(QUOTE);
    if (soapAction != null)
      sb.append(soapAction);
    sb.append(QUOTE);
    sb.append(NEW_LINE);
    return sb.toString();
  }
  
  private String getCookie()
  {
    if (maintainSession)
      return getHTTPHeader(HTTP_HEADER_COOKIE, cookie);
    else
      return EMPTY_STRING;
  }
  
  private String getCookie2()
  {
    if (maintainSession)
      return getHTTPHeader(HTTP_HEADER_COOKIE2, cookie2);
    else
      return EMPTY_STRING;
  }
  
  private String getWWWAuthentication()
  {
    if (httpBasicAuthUsername != null && httpBasicAuthPassword != null)
    {
      StringBuffer sb = new StringBuffer(httpBasicAuthUsername);
      sb.append(COLON);
      sb.append(httpBasicAuthPassword);
      BASE64Encoder encoder = new BASE64Encoder();
      String encodedUserNamePassword = encoder.encode(sb.toString().getBytes());
      sb.setLength(0);
      sb.append(HTTP_HEADER_AUTH);
      sb.append(COLON);
      sb.append(SPACE);
      sb.append(BASIC);
      sb.append(SPACE);
      sb.append(encodedUserNamePassword);
      sb.append(NEW_LINE);
      return sb.toString();
    }
    else
      return EMPTY_STRING;
  }
  
  private String getProxyAuthentication()
  {
    String proxyUserName = System.getProperty(SYS_PROP_HTTP_PROXY_USER_NAME);
    String proxyPassword = System.getProperty(SYS_PROP_HTTP_PROXY_PASSWORD);
    if (proxyUserName != null && proxyPassword != null)
    {
      StringBuffer sb = new StringBuffer(proxyUserName);
      sb.append(COLON);
      sb.append(proxyPassword);
      BASE64Encoder encoder = new BASE64Encoder();
      String encodedUserNamePassword = encoder.encode(sb.toString().getBytes());
      sb.setLength(0);
      sb.append(HTTP_HEADER_PROXY_AUTH);
      sb.append(COLON);
      sb.append(SPACE);
      sb.append(BASIC);
      sb.append(SPACE);
      sb.append(encodedUserNamePassword);
      sb.append(NEW_LINE);
      return sb.toString();
    }
    else
      return EMPTY_STRING;
  }
  
  private String getAccept()
  {
    return getHTTPHeader(HTTP_HEADER_ACCEPT, ACCEPT_VALUE);
  }
  
  private String getUserAgent()
  {
    return getHTTPHeader(HTTP_HEADER_USER_AGENT, IBM_WEB_SERVICES_EXPLORER);
  }
  
  private String getCacheControl()
  {
    return getHTTPHeader(HTTP_HEADER_CACHE_CONTROL, NO_CACHE);
  }
  
  private String getPragma()
  {
    return getHTTPHeader(HTTP_HEADER_PRAGMA, NO_CACHE);
  }
  
  private String getConnection()
  {
    return getHTTPHeader(HTTP_HEADER_CONNECTION, CLOSE);
  }
  
  private String getHTTPHeader(String key, String value)
  {
    if (value != null)
    {
      StringBuffer sb = new StringBuffer(key);
      sb.append(COLON);
      sb.append(SPACE);
      sb.append(value);
      sb.append(NEW_LINE);
      return sb.toString();
    }
    else
      return EMPTY_STRING;
  }

  public void send(URL url, String soapAction, String payload) throws UnknownHostException, IOException
  {
    StringBuffer httpHeader = new StringBuffer();
    httpHeader.append(getMethod(url));
    httpHeader.append(getHost(url));
    httpHeader.append(getContentType());
    httpHeader.append(getContentLength(payload));
    httpHeader.append(getAccept());
    httpHeader.append(getUserAgent());
    httpHeader.append(getCacheControl());
    httpHeader.append(getPragma());
    httpHeader.append(getSOAPAction(soapAction));
    httpHeader.append(getWWWAuthentication());
    httpHeader.append(getProxyAuthentication());
    httpHeader.append(getCookie());
    httpHeader.append(getCookie2());
    httpHeader.append(getConnection());
    httpHeader.append(NEW_LINE); // new line between the HTTP header and the payload
    Socket socket = buildSocket(url);
    InputStream is = socket.getInputStream();
    OutputStream os = socket.getOutputStream();
    os.write(httpHeader.toString().getBytes(DEFAULT_HTTP_HEADER_ENCODING));
    os.write(payload.getBytes(DEFAULT_SOAP_ENCODING));
    os.flush();
    httpResponse = new HTTPResponse();
    readHTTPResponseHeader(is, httpResponse);
    int code = httpResponse.getStatusCode();
    if (code == HTTP_CODE_CONTINUE)
    {
      httpResponse.reset();
      readHTTPResponseHeader(is, httpResponse);
    }
    readHTTPResponsePayload(is, httpResponse);
    os.close();
    is.close();
    socket.close();
    code = httpResponse.getStatusCode();
    String contentType = httpResponse.getHeader(HTTP_HEADER_CONTENT_TYPE.toLowerCase());
    if (code >= HTTP_CODE_EXCEPTION && (contentType == null || contentType.toLowerCase().indexOf(TEXT_XML.toLowerCase()) == -1))
      throw new HTTPException(code, httpResponse.getStatusMessage(), httpResponse.getHeaders());
  }

  private void readHTTPResponseHeader(InputStream is, HTTPResponse resp) throws IOException
  {
    byte b = 0;
    int len = 0;
    int colonIndex = -1;
    String key;
    String value;
    boolean readTooMuch = false;
    ByteArrayOutputStream baos;
    for (baos = new ByteArrayOutputStream(4096);;)
    {
      if (!readTooMuch)
        b = (byte)is.read();
      if (b == -1)
        break;
      readTooMuch = false;
      if ((b != R) && (b != N))
      {
        if ((b == COLON) && (colonIndex == -1))
          colonIndex = len;
        len++;
        baos.write(b);
      }
      else if (b == R)
        continue;
      else // b == N
      {
        if (len == 0)
          break;
        b = (byte)is.read();
        readTooMuch = true;
        // A space or tab at the begining of a line means the header continues.
        if ((b == SPACE) || (b == TAB))
          continue;
        baos.close();
        byte[] bArray = baos.toByteArray();
        baos.reset();
        if (colonIndex != -1)
        {
          key = new String(bArray, 0, colonIndex, DEFAULT_HTTP_HEADER_ENCODING);
          value = new String(bArray, colonIndex + 1, len - 1 - colonIndex, DEFAULT_HTTP_HEADER_ENCODING);
          colonIndex = -1;
        }
        else
        {
          key = new String(bArray, 0, len, DEFAULT_HTTP_HEADER_ENCODING);
          value = EMPTY_STRING;
        }
        if (!resp.isStatusSet())
        {
          // Reader status code
          int start = key.indexOf(SPACE) + 1;
          String s = key.substring(start).trim();
          int end = s.indexOf(SPACE);
          if (end != -1)
            s = s.substring(0, end);
          try
          {
            resp.setStatusCode(Integer.parseInt(s));
          }
          catch (NumberFormatException nfe)
          {
            resp.setStatusCode(-1);
          }
          resp.setStatusMessage(key.substring(start + end + 1));
        }
        else
          resp.addHeader(key.toLowerCase().trim(), value.trim());
        len = 0;
      }
    }
    baos.close();
  }

  private void readHTTPResponsePayload(InputStream is, HTTPResponse resp) throws IOException
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try
    {
      byte b = (byte)is.read();
      while (b != -1)
      {
        baos.write(b);
        b = (byte)is.read();
      }
    }
    catch (SocketTimeoutException ste)
    {
    }
    baos.close();
    resp.setPayload(baos.toByteArray());
  }

  public BufferedReader receive()
  {
    if (httpResponse != null)
    {
      try
      {
        byte[] payload = httpResponse.getPayload();
        Element soapEnvelope = null;
        if (CHUNKED.equalsIgnoreCase(httpResponse.getHeader(HTTP_HEADER_TRANSFER_ENCODEING.toLowerCase())))
        {
          ByteArrayInputStream bais = new ByteArrayInputStream(payload);
          ChunkedInputStream cis = new ChunkedInputStream(bais);
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          byte b;
          while ((b = (byte)cis.read()) != -1)
            baos.write(b);
          baos.close();
          cis.close();
          bais.close();
          soapEnvelope = XMLUtils.byteArrayToElement(baos.toByteArray(), false);
        }
        else
        {
          soapEnvelope = XMLUtils.byteArrayToElement(payload, false);
        }
        // remove XML namespace declaration
        if (soapEnvelope != null)
          return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(XMLUtils.serialize(soapEnvelope, true).getBytes(DEFAULT_SOAP_ENCODING)), DEFAULT_SOAP_ENCODING));
      }
      catch (Throwable t)
      {
      }
    }
    return null;
  }

  public Hashtable getHeaders()
  {
    Hashtable headers = new Hashtable();
    if (httpResponse != null)
      headers.putAll(httpResponse.getHeaders());
    return headers;
  }

  private Socket buildSocket(URL url) throws UnknownHostException, IOException
  {
    Socket s = null;
    String host = url.getHost();
    int port = url.getPort();
    String proxyHost = System.getProperty(SYS_PROP_HTTP_PROXY_HOST);
    int proxyPort = Integer.getInteger(SYS_PROP_HTTP_PROXY_PORT, DEFAULT_HTTP_PORT).intValue();
//    String proxyUserName = System.getProperty(SYS_PROP_HTTP_PROXY_USER_NAME);
//    String proxyPassword = System.getProperty(SYS_PROP_HTTP_PROXY_PASSWORD);
    if (url.getProtocol().equalsIgnoreCase(HTTPS))
    {
      proxyHost = System.getProperty(SYS_PROP_HTTPS_PROXY_HOST);
      proxyPort = Integer.getInteger(SYS_PROP_HTTPS_PROXY_PORT, DEFAULT_HTTPS_PORT).intValue();
      if (proxyHost != null && proxyHost.length() > 0)
      {
        // TODO:
        // SSL with proxy server
      }
      else
        s = SSLSocketFactory.getDefault().createSocket(host, (port > 0 ? port : DEFAULT_HTTPS_PORT));
      // Removing dependency on soap.jar
      //  s = SSLUtils.buildSSLSocket(host, (port > 0 ? port : DEFAULT_HTTPS_PORT), proxyHost, proxyPort);
      // TODO:
      // Build an SSL socket that supports proxyUser and proxyPassword,
      // as demonstrated in the following (original) line of code:
      //  s = SSLUtils.buildSSLSocket(host, (port > 0 ? port : DEFAULT_HTTPS_PORT), proxyHost, proxyPort, proxyUserName, proxyPassword);
    }
    else if (proxyHost != null && proxyHost.length() > 0)
      s = new Socket(proxyHost, proxyPort);
    else
      s = new Socket(host, (port > 0 ? port : DEFAULT_HTTP_PORT));
    return s;
  }
}