/*******************************************************************************
 * Copyright (c) 2003, 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.jst.ws.internal.axis.consumption.ui.task;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.internal.plugin.JavaEMFNature;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaHelpers;
import org.eclipse.jem.java.JavaParameter;
import org.eclipse.jem.java.JavaVisibilityKind;
import org.eclipse.jem.java.Method;
import org.eclipse.jem.java.impl.JavaClassImpl;
import org.eclipse.jst.ws.internal.axis.consumption.ui.util.WSDLUtils;
import org.eclipse.jst.ws.internal.common.ResourceUtils;
import org.eclipse.jst.ws.internal.plugin.WebServicePlugin;
import org.eclipse.wst.command.internal.env.common.FileResourceUtils;
import org.eclipse.wst.command.internal.provisional.env.core.common.ProgressMonitor;
import org.eclipse.wst.command.internal.provisional.env.core.common.StatusHandler;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;

public class Stub2BeanInfo
{
  private final String NEW_LINE = System.getProperty("line.separator");

  private int indentCount;

  private String package_;
  private StringBuffer imports_;
  private StringBuffer seis_;
  private StringBuffer services_;
  private StringBuffer jndiNames_;
  private StringBuffer ports_;
  private String class_;
  private Vector usedNames;
  
  private IProject clientProject_;
  private String moduleName_;
  
  public Stub2BeanInfo()
  {
    indentCount = 0;
    package_ = null;
    imports_ = new StringBuffer();
    seis_ = new StringBuffer();
    services_ = new StringBuffer();
    jndiNames_ = new StringBuffer();
    ports_ = new StringBuffer();
    class_ = "SEIBean";
    usedNames = new Vector();
  }

  public void setClientProject(IProject clientProject) {
  	this.clientProject_ =  clientProject;
  }
  
  public void setClientModuleName(String moduleName) {
	  this.moduleName_ = moduleName;
  }

  public void setPackage(String pkgName)
  {
    if (pkgName != null && pkgName.length() > 0)
      package_ = manglePackageName(pkgName);
  }

  public void addImports(String pkgName, String className)
  {
    imports_.append(toFullyQualifiedClassName(pkgName, className));
    imports_.append(";");
  }

  public void addSEI(String seiPkgName, String seiClassName, String servicePkgName, String serviceClassName, String portName)
  {
    addSEI(seiPkgName, seiClassName, servicePkgName, serviceClassName, serviceClassName, portName);
  }

  public void addSEI(String seiPkgName, String seiClassName, String servicePkgName, String serviceClassName, String jndiName, String portName)
  {
    seis_.append(toFullyQualifiedClassName(seiPkgName, seiClassName));
    seis_.append(";");
    services_.append(toFullyQualifiedClassName(servicePkgName, serviceClassName));
    services_.append(";");
    jndiNames_.append(jndiName);
    jndiNames_.append(";");
    ports_.append(portName);
    ports_.append(";");
  }

  public void setClass(String className)
  {
    if (className != null && className.length() > 0)
      class_ = mangleClassName(className);
  }

  private String toFullyQualifiedClassName(String pkgName, String className)
  {
    StringBuffer sb = new StringBuffer();
    sb.append(manglePackageName(pkgName));
    sb.append(".");
    sb.append(mangleClassName(className));
    return sb.toString();
  }

  private String getPackageName(String qname)
  {
    int index = qname.lastIndexOf(".");
    if (index != -1)
      return qname.substring(0, index);
    else
      return qname;
  }

  private String getClassName(String qname)
  {
    int index = qname.lastIndexOf(".");
    if (index != -1)
      return qname.substring(index+1, qname.length());
    else
      return qname;
  }

  private String manglePackageName(String s)
  {
    return replaceInvalidJavaChars(s);
  }

  private String mangleClassName(String s)
  {
    s = firstCharToUpperCase(WSDLUtils.resolveDotInPortName(s));
    return replaceInvalidJavaChars(s);
  }

  private String replaceInvalidJavaChars(String s)
  {
    char[] c = s.toCharArray();
    for (int i = 0; i < c.length; i++)
    {
      if (!Character.isJavaIdentifierPart(c[i]))
        c[i] = '.';
    }
    return new String(c);
  }

  private String firstCharToUpperCase(String s)
  {
    StringBuffer sb = new StringBuffer();
    sb.append(s.substring(0, 1).toUpperCase());
    sb.append(s.substring(1, s.length()));
    return sb.toString();
  }

  private String firstCharToLowerCase(String s)
  {
    StringBuffer sb = new StringBuffer();
    sb.append(s.substring(0, 1).toLowerCase());
    sb.append(s.substring(1, s.length()));
    return sb.toString();
  }

  private String trimArraySymbol(String s)
  {
    int index = s.indexOf("[");
    if (index != -1)
      return s.substring(0, index);
    else
      return s;
  }

  private String getFullyQualifiedName(JavaHelpers javaHelpers)
  {
    if (javaHelpers.isPrimitive())
      return javaHelpers.getJavaName();
    else
      return javaHelpers.getQualifiedName();
  }

  public void write(ProgressMonitor progressMonitor, StatusHandler statusMonitor) throws CoreException, IOException
  {
    StringWriter sw = new StringWriter(2048);
    writePackage(sw);
    writeImports(sw);
    writeClass(sw);
    sw.close();
    byte[] bytes = sw.getBuffer().toString().getBytes();
    StringBuffer sb = new StringBuffer();
    if (package_ != null && package_.length() > 0)
    {
      sb.append(package_);
      sb.append(".");
    }
    sb.append(class_);
    sb = new StringBuffer(sb.toString().replace('.', '/'));
    sb.append(".java");

    JavaEMFNature javaMOF = (JavaEMFNature)JavaEMFNature.createRuntime(clientProject_);
    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
    IPath sourceFolderPath = null;
    IPath filePath = null;
    ModuleCoreNature mn = ModuleCoreNature.getModuleCoreNature(clientProject_);
    if (mn!=null)
    {
    	sourceFolderPath = ResourceUtils.getJavaSourceLocation(clientProject_, moduleName_);
        IFolder sourceFolder = (IFolder)ResourceUtils.findResource(sourceFolderPath);
        filePath = sourceFolder.getFile(new Path(sb.toString())).getFullPath();    	
    }
    else
    {
        // It's a plain old Java project
    	IJavaProject javaProject = null;    	  
		javaProject = JavaCore.create(clientProject_);

		sourceFolderPath = ResourceUtils.getJavaSourceLocation(clientProject_);
		IResource sourceFolderResource = ResourceUtils.findResource(sourceFolderPath);
		if (sourceFolderResource instanceof IFolder) 
		{
				IFolder sourceFolder = (IFolder) sourceFolderResource;
				filePath = sourceFolder.getFile(new Path(sb.toString())).getFullPath();
		} else 
		{
			// The source must be going directly in the project
			filePath = clientProject_.getFile(new Path(sb.toString())).getFullPath();
		}
		
    }

    FileResourceUtils.createFile(WebServicePlugin.getInstance().getResourceContext(), filePath, bais, progressMonitor, statusMonitor);
  }

  private void writePackage(Writer w) throws IOException
  {
    if (package_ != null && package_.length() > 0)
    {
      w.write("package ");
      w.write(package_);
      w.write(";");
      newLine(w);
    }
  }

  private void writeImports(Writer w) throws IOException
  {
    StringTokenizer st = new StringTokenizer(imports_.toString(), ";");
    while (st.hasMoreTokens())
    {
      w.write("import ");
      w.write(st.nextToken());
      w.write(";");
      newLine(w);
    }
  }

  private void writeClass(Writer w) throws IOException, CoreException
  {
    newLine(w);
    w.write("public class ");
    w.write(class_);
    w.write(" ");
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    if (st.hasMoreTokens())
      w.write("implements ");
    while (st.hasMoreTokens())
    {
      w.write(st.nextToken());
      if (st.hasMoreTokens())
        w.write(", ");
    }
    w.write(" {");
    incrementIndent();
    newLine(w);
    writeFieldsDeclarations(w);
    writeConstructor(w);
    writeInit(w);
    /*
    * Cannot use JNDI lookup for AXIS
    *
    writeUseJNDI(w);
    */
    writeGetSetEndpoint(w);
    writeSEIGetters(w);
    writeSEIMethods(w);
    decrementIndent();
    newLine(w);
    w.write("}");
  }

  private void writeFieldsDeclarations(Writer w) throws IOException
  {
    /*
    * Cannot use JNDI lookup for AXIS
    *
    w.write("private boolean _useJNDI = true;");
    newLine(w);
    */
    w.write("private String _endpoint = null;");
    usedNames.add("_endpoint");
    newLine(w);
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    while (st.hasMoreTokens())
    {
      w.write("private ");
      String sei = st.nextToken();
      w.write(sei);
      w.write(" ");
      String stubName = firstCharToLowerCase(getClassName(sei));
      w.write(stubName);
      usedNames.add(stubName);
      w.write(" = null;");
      newLine(w);
    }
  }

  private void writeConstructor(Writer w) throws IOException
  {
    newLine(w);
    w.write("public ");
    w.write(class_);
    w.write("() {");
    incrementIndent();
    newLine(w);
    w.write("_init");
    w.write(class_);
    w.write("();");
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
  }

  private void writeInit(Writer w) throws IOException
  {
    newLine(w);
    w.write("private void _init");
    w.write(class_);
    w.write("() {");
    incrementIndent();
    newLine(w);
    w.write("try {");
    incrementIndent();
    newLine(w);
    /*
    * Cannot use JNDI lookup for AXIS
    *
    w.write("if (_useJNDI) {");
    incrementIndent();
    newLine(w);
    */
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    StringTokenizer serviceTokens = new StringTokenizer(services_.toString(), ";");
    StringTokenizer jndiNameTokens = new StringTokenizer(jndiNames_.toString(), ";");
    StringTokenizer portTokens = new StringTokenizer(ports_.toString(), ";");
    /*
    if (st.hasMoreTokens())
    {
      w.write("javax.naming.InitialContext ctx = new javax.naming.InitialContext();");
      newLine(w);
    }
    while (st.hasMoreTokens())
    {
      w.write(firstCharToLowerCase(getClassName(st.nextToken())));
      w.write(" = ((");
      w.write(serviceTokens.nextToken());
      w.write(")ctx.lookup(\"java:comp/env/service/");
      w.write(jndiNameTokens.nextToken());
      w.write("\")).get");
      w.write(mangleClassName(portTokens.nextToken()));
      w.write("();");
      newLine(w);
    }
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
    w.write("else {");
    incrementIndent();
    newLine(w);
    st = new StringTokenizer(seis_.toString(), ";");
    serviceTokens = new StringTokenizer(services_.toString(), ";");
    portTokens = new StringTokenizer(ports_.toString(), ";");
    */
    while (st.hasMoreTokens())
    {
      String seiName = firstCharToLowerCase(getClassName(st.nextToken()));
      w.write(seiName);
      w.write(" = (new ");
      w.write(serviceTokens.nextToken());
      w.write("Locator()).get");
      w.write(replaceInvalidJavaChars(WSDLUtils.resolveDotInPortName(portTokens.nextToken())));
      w.write("();");
      newLine(w);
      w.write("if (");
      w.write(seiName);
      w.write(" != null) {");
      incrementIndent();
      newLine(w);
      w.write("if (_endpoint != null)");
      incrementIndent();
      newLine(w);
      w.write("((javax.xml.rpc.Stub)");
      w.write(seiName);
      w.write(")._setProperty(\"javax.xml.rpc.service.endpoint.address\", _endpoint);");
      decrementIndent();
      newLine(w);
      w.write("else");
      incrementIndent();
      newLine(w);
      w.write("_endpoint = (String)((javax.xml.rpc.Stub)");
      w.write(seiName);
      w.write(")._getProperty(\"javax.xml.rpc.service.endpoint.address\");");
      decrementIndent();
      decrementIndent();
      newLine(w);
      w.write("}");
      newLine(w);
    }
    /*
    decrementIndent();
    newLine(w);
    w.write("}");
    */
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
    /*
    w.write("catch (javax.naming.NamingException namingException) {}");
    newLine(w);
    */
    w.write("catch (javax.xml.rpc.ServiceException serviceException) {}");
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
  }

  private void writeSetPropertyEndpoint(Writer w) throws IOException
  {
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    while (st.hasMoreTokens())
    {
      String seiName = firstCharToLowerCase(getClassName(st.nextToken()));
      w.write("if (");
      w.write(seiName);
      w.write(" != null)");
      incrementIndent();
      newLine(w);
      w.write("((javax.xml.rpc.Stub)");
      w.write(seiName);
      w.write(")._setProperty(\"javax.xml.rpc.service.endpoint.address\", _endpoint);");
      decrementIndent();
      newLine(w);
    }
  }

  private void writeUseJNDI(Writer w) throws IOException
  {
    newLine(w);
    w.write("public void useJNDI(boolean useJNDI) {");
    incrementIndent();
    newLine(w);
    w.write("_useJNDI = useJNDI;");
    newLine(w);
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    while (st.hasMoreTokens())
    {
      w.write(firstCharToLowerCase(getClassName(st.nextToken())));
      w.write(" = null;");
      newLine(w);
    }
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
  }

  private void writeSEIGetters(Writer w) throws IOException
  {
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    while (st.hasMoreTokens())
    {
      String sei = st.nextToken();
      String seiClassName = getClassName(sei);
      String seiFieldName = firstCharToLowerCase(seiClassName);
      newLine(w);
      w.write("public ");
      w.write(sei);
      w.write(" get");
      w.write(seiClassName);
      w.write("() {");
      incrementIndent();
      newLine(w);
      w.write("if (");
      w.write(seiFieldName);
      w.write(" == null)");
      incrementIndent();
      newLine(w);
      w.write("_init");
      w.write(class_);
      w.write("();");
      decrementIndent();
      newLine(w);
      w.write("return ");
      w.write(seiFieldName);
      w.write(";");
      decrementIndent();
      newLine(w);
      w.write("}");
      newLine(w);
    }
  }

  private void writeSEIMethods(Writer w) throws IOException, CoreException
  {
    newLine(w);
    //WebServiceElement wse = WebServiceElement.getWebServiceElement(model_);
    if (clientProject_ == null) return;//wse.getProxyProject();
    JavaEMFNature javaMOF = (JavaEMFNature)JavaEMFNature.createRuntime(clientProject_);
    StringTokenizer st = new StringTokenizer(seis_.toString(), ";");
    while (st.hasMoreTokens())
    {
      String sei = st.nextToken();
      JavaClass javaClass = (JavaClass)JavaClassImpl.reflect(getPackageName(sei), getClassName(sei), javaMOF.getResourceSet());
      if (javaClass != null)
      {
        List methods = javaClass.getMethods();
        for (Iterator it = methods.iterator(); it.hasNext();)
        {
          Method method = (Method)it.next();
          if (!method.isConstructor() && !method.isNative() && method.getJavaVisibility().getValue() == JavaVisibilityKind.PUBLIC)
            writeSEIMethods(w, javaClass, method);
        }
      }
    }
  }

  private void writeSEIMethods(Writer w, JavaClass javaClass, Method method) throws IOException
  {
    w.write("public ");
    // isVoid
    if (method.isVoid())
      w.write("void ");
    else
    {
      w.write(getFullyQualifiedName(method.getReturnType()));
      w.write(" ");
    }
    // method name
    w.write(method.getName());
    w.write("(");
    // input parameters
    JavaParameter[] inputParams = method.listParametersWithoutReturn();
    for (int i = 0; i < inputParams.length; i++)
    {
      if (i > 0)
        w.write(", ");
      JavaHelpers javaHelpers = inputParams[i].getJavaType();
      w.write(getFullyQualifiedName(javaHelpers));
      w.write(" ");
      String paramName = getClassName(inputParams[i].getQualifiedName());
      w.write(getUnusedName(paramName));
    }
    w.write(")");
    // exceptions
    List exceptions = method.getJavaExceptions();
    if (!exceptions.isEmpty())
      w.write(" throws ");
    for (Iterator it = exceptions.iterator(); it.hasNext();)
    {
      JavaClass exception = (JavaClass)it.next();
      w.write(exception.getQualifiedNameForReflection());
      if (it.hasNext())
        w.write(", ");
    }
    // method body
    w.write("{");
    incrementIndent();
    newLine(w);
    String stubName = firstCharToLowerCase(javaClass.getName());
    w.write("if (");
    w.write(stubName);
    w.write(" == null)");
    incrementIndent();
    newLine(w);
    w.write("_init");
    w.write(class_);
    w.write("();");
    decrementIndent();
    newLine(w);
    if (!method.isVoid())
      w.write("return ");
    w.write(stubName);
    w.write(".");
    w.write(method.getName());
    w.write("(");
    for (int i = 0; i < inputParams.length; i++)
    {
      if (i > 0)
        w.write(", ");
      String paramName = getClassName(inputParams[i].getQualifiedName());
      w.write(getUnusedName(paramName));
    }
    w.write(");");
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
    newLine(w);
  }

  private void writeGetSetEndpoint(Writer w) throws IOException
  {
    newLine(w);
    w.write("public String getEndpoint() {");
    incrementIndent();
    newLine(w);
    w.write("return _endpoint;");
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
    newLine(w);
    w.write("public void setEndpoint(String endpoint) {");
    incrementIndent();
    newLine(w);
    w.write("_endpoint = endpoint;");
    newLine(w);
    writeSetPropertyEndpoint(w);
    decrementIndent();
    newLine(w);
    w.write("}");
    newLine(w);
  }

  private void createParentFolder(IResource res) throws CoreException
  {
    IResource parent = res.getParent();
    if (parent != null && parent != res && parent instanceof IFolder)
    {
      IFolder folder = (IFolder)parent;
      if (!folder.exists())
      {
        createParentFolder(folder);
        folder.create(true, true, null);
      }
    }
  }

  private void incrementIndent()
  {
    indentCount++;
  }

  private void decrementIndent()
  {
    indentCount--;
  }

  private void indent(Writer w) throws IOException
  {
    for (int i = 0; i < indentCount; i++)
      w.write("  ");
  }

  private void newLine(Writer w) throws IOException
  {
    w.write(NEW_LINE);
    indent(w);
  }
  
  private String getUnusedName(String name)
  {
    if (usedNames.contains(name))
    {
      for (int i = 0; i < 100; i++)
      {
        String newName = (new StringBuffer(name)).append(String.valueOf(i)).toString();
        if (!usedNames.contains(newName))
          return newName;
      }
    }
    return name;
  }
}
