/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.wst.ws.internal.wsil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

import javax.wsdl.Definition;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.wsil.Abstract;
import org.apache.wsil.Description;
import org.apache.wsil.Inspection;
import org.apache.wsil.QName;
import org.apache.wsil.Service;
import org.apache.wsil.WSILDocument;
import org.apache.wsil.WSILException;
import org.apache.wsil.extension.ExtensionBuilder;
import org.apache.wsil.extension.wsdl.ImplementedBinding;
import org.apache.wsil.extension.wsdl.Reference;
import org.apache.wsil.extension.wsdl.ReferencedService;
import org.apache.wsil.extension.wsdl.WSDLConstants;
import org.apache.wsil.xml.XMLWriter;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.command.internal.env.core.common.StatusUtils;
import org.eclipse.wst.common.environment.IEnvironment;
import org.eclipse.wst.common.environment.uri.IURIFactory;
import org.eclipse.wst.common.environment.uri.URIException;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.ws.internal.parser.wsil.IllegalArgumentsException;
import org.eclipse.wst.ws.internal.parser.wsil.WSILMessages;
import org.eclipse.wst.ws.internal.parser.wsil.WWWAuthenticationException;
import org.eclipse.wst.ws.internal.parser.wsil.WWWAuthenticationHandler;
import org.eclipse.wst.ws.internal.parser.wsil.WebServicesParser;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class AddWSDLToWSILCommand extends AbstractDataModelOperation
{
  public static final String ARG_WSIL = "-wsil";
  public static final String ARG_WSDL = "-wsdl";
  public static final String ARG_RESOLVE_WSDL = "-resolvewsdl";
  public static final String ARG_HTTP_BASIC_AUTH_USERNAME = "-httpusername";
  public static final String ARG_HTTP_BASIC_AUTH_PASSWORD = "-httppassword";
  private WWWAuthenticationHandler wwwAuthHandler_;
  private String[] args_;
  private String wsil_;
  private ArrayList wsdls_;
  private boolean resolveWSDL_;
  private String httpUsername_;
  private String httpPassword_;

  public AddWSDLToWSILCommand()
  {
    wwwAuthHandler_ = null;
    args_ = new String[0];
    clearParsedArgs();
  }

  private void clearParsedArgs()
  {
    wsil_ = null;
    if (wsdls_ == null)
      wsdls_ = new ArrayList();
    else
      wsdls_.clear();
    resolveWSDL_ = false;
    httpUsername_ = null;
    httpPassword_ = null;
  }

  /**
   * Executes the Command.
   * 
   * @param environment
   *            The environment. Must not be null.
   * @return A <code>Status</code> object indicating the degree to which the
   *         <code>execute</code> method was successful. A valud of <code>null</code>,
   *         or a Status with a severity of less than <code>Status.ERROR</code>
   *         signifies success.
   */
  public IStatus execute( IProgressMonitor monitor, IAdaptable adaptable )
  {
    IEnvironment environment = getEnvironment();
    
    IURIFactory uriFactory = environment.getURIFactory();
    // Parse arguments
    try
    {
      parseArguments();
    }
    catch (IllegalArgumentsException iae)
    {
      return StatusUtils.errorStatus( WSILMessages.MSG_ERROR_ILLEGAL_ARGUMENTS, iae);
    }
    catch (ArrayIndexOutOfBoundsException e)
    {
      return StatusUtils.errorStatus( WSILMessages.MSG_ERROR_INVALID_ARGUMENTS, e);
    }
    // Create new WSIL document
    WSILDocument wsilDocument = null;
    URL wsilURL = null;
    try
    {
      wsilDocument = WSILDocument.newInstance();
      wsilURL = new URL(wsil_);
    }
    catch (MalformedURLException murle)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_INVALID_WSIL_URI, murle);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    catch (WSILException wsile)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, wsile);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    // Read WSIL
    try
    {
      InputStream is = uriFactory.newURI(wsilURL).getInputStream();
      if (is != null)
      {
        wsilDocument.read(new InputStreamReader(is));
        is.close();
      }
    }
    catch (URIException urie)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, urie);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    catch (IOException ioe)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, ioe);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    catch (WSILException wsile)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, wsile);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    // internalExecute
    String httpUsername = null;
    String httpPassword = null;
    if (wsdls_.size() == 1 && httpUsername_ != null && httpPassword_ != null)
    {
      httpUsername = httpUsername_;
      httpPassword = httpPassword_;
    }
    for (Iterator it = wsdls_.iterator(); it.hasNext();)
    {
      String wsdl = (String) it.next();
      IStatus status = null;
      try
      {
        status = internalExecute(environment, wsilDocument, platform2File(uriFactory, wsil_), wsdl, httpUsername, httpPassword);
      }
      catch (WWWAuthenticationException wwwae)
      {
        if (wwwAuthHandler_ != null && httpUsername == null && httpPassword == null)
        {
          wwwAuthHandler_.handleWWWAuthentication(wwwae);
          String handlerUsername = wwwAuthHandler_.getUsername();
          String handlerPassword = wwwAuthHandler_.getPassword();
          if (handlerUsername != null && handlerPassword != null)
          {
            try
            {
              status = internalExecute(environment, wsilDocument, platform2File(uriFactory, wsil_), wsdl, handlerUsername, handlerPassword);
            }
            catch (WWWAuthenticationException wwwae2)
            {
              IStatus wwwaeStatus = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNRESOLVABLE_WSDL, wwwae2.getIOException());
              environment.getStatusHandler().reportError(wwwaeStatus);
              return wwwaeStatus;
            }
          }
        }
        if (status == null)
        {
          IStatus s = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNRESOLVABLE_WSDL, wwwae.getIOException());
          environment.getStatusHandler().reportError(s);
          return s;
        }
      }
      if (status.getSeverity() != Status.OK)
        return status;
    }
    // Write WSIL
    try
    {
      XMLWriter xmlWriter = new XMLWriter();
      OutputStream os = uriFactory.newURI(wsilURL).getOutputStream();
      if (os != null)
        xmlWriter.writeDocument(wsilDocument, os);
      else
        throw new IOException();
      os.close();
    }
    catch (URIException urie)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_WRITE_WSIL, urie);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    catch (IOException ioe)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_WRITE_WSIL, ioe);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    catch (WSILException wsile)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_WRITE_WSIL, wsile);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    return Status.OK_STATUS;
  }

  private IStatus internalExecute(IEnvironment environment, WSILDocument wsilDocument, String wsil, String wsdl, String httpUsername, String httpPassword) throws WWWAuthenticationException
  {
    Definition definition = null;
    ArrayList wsdlService = new ArrayList();
    ArrayList wsdlBinding = new ArrayList();
    if (resolveWSDL_)
    {
      // Parse WSDL
      try
      {
        definition = parseWSDL(wsdl, wsdlService, wsdlBinding, httpUsername, httpPassword);
      }
      catch (MalformedURLException murle)
      {
        IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_INVALID_WSDL_URI, murle);
        environment.getStatusHandler().reportError(status);
        return status;
      }
      catch (IOException ioe)
      {
        IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNRESOLVABLE_WSDL, ioe);
        environment.getStatusHandler().reportError(status);
        return status;
      }
      catch (ParserConfigurationException pce)
      {
        IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, pce);
        environment.getStatusHandler().reportError(status);
        return status;
      }
      catch (SAXException saxe)
      {
        IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_MALFORMED_WSDL, saxe);
        environment.getStatusHandler().reportError(status);
        return status;
      }
    }
    // Add WSDL to WSIL
    try
    {
      Inspection inspection = wsilDocument.getInspection();
      Service service = wsilDocument.createService();
      if (definition != null)
      {
        Element documentation = definition.getDocumentationElement();
        Abstract serviceAbstract = wsilDocument.createAbstract();
        serviceAbstract.setText(Element2String(documentation));
        service.addAbstract(serviceAbstract);
      }
      Description desc = wsilDocument.createDescription();
      desc.setReferencedNamespace(WSDLConstants.NS_URI_WSDL);
      desc.setLocation(getRelativeURI(wsil, wsdl));
      ExtensionBuilder extBuilder = wsilDocument.getExtensionRegistry().getBuilder(WSDLConstants.NS_URI_WSIL_WSDL);
      if (definition == null || endpointPresent(definition))
      {
        for (Iterator it = wsdlService.iterator(); it.hasNext();)
        {
          Reference reference = (Reference) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REFERENCE));
          reference.setEndpointPresent(new Boolean(true));
          ReferencedService refService = (ReferencedService) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REF_SERVICE));
          refService.setReferencedServiceName((QName) it.next());
          reference.setReferencedService(refService);
          desc.setExtensionElement(reference);
        }
      }
      else
      {
        Reference reference = (Reference) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_REFERENCE));
        reference.setEndpointPresent(new Boolean(false));
        for (Iterator it = wsdlBinding.iterator(); it.hasNext();)
        {
          ImplementedBinding binding = (ImplementedBinding) extBuilder.createElement(new QName(WSDLConstants.NS_URI_WSIL_WSDL, WSDLConstants.ELEM_IMPL_BINDING));
          binding.setBindingName((QName) it.next());
          reference.addImplementedBinding(binding);
        }
      }
      service.addDescription(desc);
      inspection.addService(service);
    }
    catch (WSILException wsile)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, wsile);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    catch (Throwable t)
    {
      IStatus status = StatusUtils.errorStatus( WSILMessages.MSG_ERROR_UNEXPECTED_EXCEPTION, t);
      environment.getStatusHandler().reportError(status);
      return status;
    }
    return Status.OK_STATUS;
  }

  /**
   * Returns <code>true</code> if, and only if, the Command's <code>undo</code>
   * method is supported.
   * 
   * @return True if the Command supports being undone.
   */
  public boolean isUndoable()
  {
    return false;
  }

  /**
   * Undoes the Command.
   * 
   * @param environment
   *            The environment. Must not be null.
   * @return A <code>Status</code> object indicating the degree to which the
   *         <code>undo</code> method was successful. A valud of <code>null</code>,
   *         or a Status with a severity of less than <code>Status.ERROR</code>
   *         signifies success.
   */
  public IStatus undo(IEnvironment environment)
  {
    return Status.OK_STATUS;
  }

  private Definition parseWSDL(String wsdl, ArrayList wsdlService, ArrayList wsdlBinding, String httpUsername, String httpPassword) throws MalformedURLException, IOException, ParserConfigurationException, SAXException, WWWAuthenticationException
  {
    WebServicesParser wsParser = new WebServicesParser(wsdl);
    if (httpUsername != null && httpPassword != null)
    {
      wsParser.setHTTPBasicAuthUsername(httpUsername);
      wsParser.setHTTPBasicAuthPassword(httpPassword);
    }
    wsParser.parse(WebServicesParser.PARSE_NONE);
    Definition definition = wsParser.getWSDLDefinition(wsdl);
    if (definition != null)
    {
      Map services = definition.getServices();
      for (Iterator it = services.keySet().iterator(); it.hasNext();)
        wsdlService.add(parseQName((javax.xml.namespace.QName) it.next()));
      Map bindings = definition.getBindings();
      for (Iterator it = bindings.keySet().iterator(); it.hasNext();)
        wsdlBinding.add(parseQName((javax.xml.namespace.QName) it.next()));
    }
    return definition;
  }

  private boolean endpointPresent(Definition definition)
  {
    return (definition.getServices().size() > 0);
  }

  public String[] getArguments()
  {
    return args_;
  }

  public void setArguments(String[] args)
  {
    args_ = args;
  }

  public WWWAuthenticationHandler getWWWAuthenticationHandler()
  {
    return wwwAuthHandler_;
  }

  public void setWWWAuthenticationHandler(WWWAuthenticationHandler wwwAuthHandler)
  {
    wwwAuthHandler_ = wwwAuthHandler;
  }

  private void parseArguments() throws IllegalArgumentsException
  {
    clearParsedArgs();
    for (int i = 0; i < args_.length; i++)
    {
      if (ARG_WSIL.equals(args_[i]))
        wsil_ = args_[++i];
      else if (ARG_WSDL.equals(args_[i]))
        wsdls_.add(args_[++i]);
      else if (ARG_RESOLVE_WSDL.equals(args_[i]))
        resolveWSDL_ = true;
      else if (ARG_HTTP_BASIC_AUTH_USERNAME.equals(args_[i]))
        httpUsername_ = args_[++i];
      else if (ARG_HTTP_BASIC_AUTH_PASSWORD.equals(args_[i]))
        httpPassword_ = args_[++i];
      else
        throw new IllegalArgumentsException(args_[i]);
    }
  }

  private QName parseQName(javax.xml.namespace.QName qname)
  {
    return new QName(qname.getNamespaceURI(), qname.getLocalPart());
  }

  private String Element2String(Element e) throws TransformerConfigurationException, TransformerException, IOException
  {
    byte[] b = new byte[0];
    if (e != null)
    {
      DOMSource domSource = new DOMSource(e);
      Transformer serializer = TransformerFactory.newInstance().newTransformer();
      serializer.setOutputProperty(OutputKeys.INDENT, "yes");
      serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      serializer.transform(domSource, new StreamResult(baos));
      baos.close();
      b = baos.toByteArray();
    }
    return new String(b);
  }

  private String platform2File(IURIFactory uriFactory, String uri)
  {
    try
    {
      return uriFactory.newURI(uri).asFile().toURL().toString();
    }
    catch (Throwable t)
    {
      t.printStackTrace();
    }
    return uri;
  }

  private final char FWD_SLASH = '/';
  private final char BWD_SLASH = '\\';
  private final String parentDir = "../";

  private String getRelativeURI(String baseURI, String targetURI)
  {
    try
    {
      String baseURICopy = baseURI.replace(BWD_SLASH, FWD_SLASH);
      String targetURICopy = targetURI.replace(BWD_SLASH, FWD_SLASH);
      int matchingIndex = -1;
      int index = targetURICopy.indexOf(FWD_SLASH);
      while (index != -1)
      {
        if (baseURICopy.startsWith(targetURICopy.substring(0, index + 1)))
        {
          matchingIndex = index;
          index = targetURICopy.indexOf(FWD_SLASH, index + 1);
        }
        else
          break;
      }
      if (matchingIndex != -1)
      {
        int slashCount = -1;
        int fromIndex = matchingIndex;
        while (fromIndex != -1)
        {
          slashCount++;
          fromIndex = baseURICopy.indexOf(FWD_SLASH, fromIndex + 1);
        }
        StringBuffer relativeURI = new StringBuffer();
        for (int i = 0; i < slashCount; i++)
          relativeURI.append(parentDir);
        relativeURI.append(targetURI.substring(matchingIndex + 1, targetURI.length()));
        return relativeURI.toString();
      }
    }
    catch (Throwable t)
    {
    }
    return targetURI;
  }
}