/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you 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 org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib;

import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.GeneratorHelper;
import org.apache.myfaces.buildtools.maven2.plugin.faces.io.PrettyWriter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.ComponentBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.PropertyBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.SourceTemplate;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.Util;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

/**
 * TODO: comment this!
 *
 * @author Bruno Aranda (latest modification by $Author$)
 * @version $Revision$ $Date$
 */
public abstract class AbstractComponentTagGenerator implements ComponentTagGenerator
{

  public void writeImports(PrettyWriter out,
                           SourceTemplate template,
                           String packageName,
                           String fullSuperclassName,
                           String superclassName,
                           ComponentBean component)
  {
    Collection components = new HashSet();
    components.add(component);
    writeImports(out, template, packageName, fullSuperclassName, superclassName, components);
  }


  public void writeImports(PrettyWriter out, SourceTemplate template, String packageName, String fullSuperclassName,
                           String superclassName, Collection components)
  {
    Set imports = new TreeSet();

    for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
    {
      ComponentBean component = (ComponentBean) lIterator.next();
      Iterator properties = component.properties();
      properties = new FilteredIterator(properties, new TagAttributeFilter());

      // TODO: remove these imports
      // FIXME: Actually last 2 can be kept when not abstract
      //imports.add("javax.faces.component.UIComponent");

      // superclassName is fully qualified if it collides
      // with the generated class name and should not be
      // imported when such a collision would occur
      if (!superclassName.equals(fullSuperclassName))
      {
        imports.add(fullSuperclassName);
      }

      while (properties.hasNext())
      {
        PropertyBean property = (PropertyBean) properties.next();

        String propertyClass = property.getPropertyClass();
        String[] propertyClassParams = property.getPropertyClassParameters();

        if (propertyClass != null && property.isLiteralOnly())
        {
          // Import the property class only if only litterals are supported
          // otherwise the class will be a String inside the tag to support
          // ValueBinding
          imports.add(propertyClass);
        }

        // TODO: restore import and make reference to
        //       ConstantMethodBinding relative rather
        //       than absolute
        //if (property.isMethodBinding() &&
        //    isStringMethodBindingReturnType(property))
        //{
        //  imports.add("org.apache.myfaces.trinidadinternal.taglib.ConstantMethodBinding");
        //}
      }

      addSpecificImports(imports, component);

    }
    // do not import implicit!
    imports.removeAll(Util.PRIMITIVE_TYPES);

    GeneratorHelper.writeImports(out, packageName, imports);
  }

  public void writeClassBegin(PrettyWriter out,
                              String className,
                              String superclassName,
                              ComponentBean component,
                              SourceTemplate template)
  {
    int modifiers = component.getTagClassModifiers();
    String classStart = Modifier.toString(modifiers);

    out.println("/**");
    out.println(" * Auto-generated tag class.");
    out.println(" */");

    // TODO: use canonical ordering
    classStart = classStart.replaceAll("public abstract", "abstract public");
    out.println(classStart + " class " + className +
        " extends " + superclassName);
    out.println("{");
    out.indent();
  }


  public void writeConstructor(PrettyWriter out,
                               ComponentBean component,
                               int modifiers) throws IOException
  {
    String fullClassName = component.getTagClass();
    String className = Util.getClassFromFullClass(fullClassName);
    out.println();
    out.println("/**");
    // TODO: restore this correctly phrased comment (tense vs. command)
    //out.println(" * Constructs an instance of " + className + ".");
    out.println(" * Construct an instance of the " + className + ".");
    out.println(" */");
    out.println("public " + className + "()");
    out.println("{");
    out.println("}");
  }

  public void writeGetComponentType(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    String componentType = component.getComponentType();
    out.println();

    // The superclass does not necessarily need to have this method
    //out.println("@Override");
    out.println("public String getComponentType()");
    out.println("{");
    out.indent();
    out.println("return \"" + componentType + "\";");
    out.unindent();
    out.println("}");
  }

  public void writeGetRendererType(
      PrettyWriter out,
      ComponentBean component) throws IOException
  {
    String rendererType = component.getRendererType();
    out.println();

    // The superclass does not necessarily need to have this method
    //out.println("@Override");
    out.println("public String getRendererType()");
    out.println("{");
    out.indent();
    out.println("return " + Util.convertStringToLiteral(rendererType) + ";");
    out.unindent();
    out.println("}");
  }

  public void writeClassEnd(PrettyWriter out)
  {
    out.unindent();
    out.println("}");
  }

  public void writePropertyMembers(PrettyWriter out,
                                   ComponentBean component) throws IOException
  {
    Iterator properties = component.properties();
    properties = new FilteredIterator(properties, new TagAttributeFilter());

    while (properties.hasNext())
    {
      PropertyBean property = (PropertyBean) properties.next();
      writePropertyDeclaration(out, property);
      writePropertySetter(out, property);
    }
  }


  public void writePropertyMembers(PrettyWriter out, Collection components) throws IOException
  {
    for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
    {
      writePropertyMembers(out, (ComponentBean) lIterator.next());
    }
  }

  public void writeReleaseMethod(PrettyWriter out,
                                 ComponentBean component) throws IOException
  {
    Collection components = new HashSet();
    components.add(component);
    writeReleaseMethod(out, components);
  }


  public void writeReleaseMethod(
    PrettyWriter out, Collection components) throws IOException
  {
    Collection all = new HashSet();
    boolean special = false;
    for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
    {
      ComponentBean component = (ComponentBean) lIterator.next();
      Iterator prop = component.properties();
      // TODO: remove special case for UIXFormTag
      special |= "org.apache.myfaces.trinidadinternal.taglib.UIXFormTag".equals(component.getTagClass());
      while (prop.hasNext())
      {
        all.add(prop.next());
      }
    }

    Iterator properties = all.iterator();
    properties = new FilteredIterator(properties, new TagAttributeFilter());
    if (properties.hasNext() || special)
    {
      out.println();
      if (is12()){
          out.println("@Override");
      }
      out.println("public void release()");
      out.println("{");
      out.indent();
      out.println("super.release();");
      while (properties.hasNext())
      {
        PropertyBean property = (PropertyBean) properties.next();
        String propName = property.getPropertyName();
        String propVar = "_" + propName;
        out.print(propVar + " = ");
        String type = GeneratorHelper.getJspPropertyType(property, is12());
        // FIXME: support all primitive types.  In practice, the only types
        // that have come up are ValueExpression, String, and boolean
        if ("boolean".equals(type))
          out.println("false;");
        else
          out.println("null;");
      }
      out.unindent();
      out.println("}");
    }
  }

  protected void addSpecificImports(
      Set imports,
      ComponentBean component)
  {
    // nothing by default
  }

  /**
   * Returns true if the method is being used for generating JSF 1.2 code.
   */
  protected abstract boolean is12();

  protected abstract void writePropertyDeclaration(PrettyWriter out,
                                                   PropertyBean property) throws IOException;

  protected abstract void writePropertySetter(PrettyWriter out,
                                              PropertyBean property) throws IOException;

  protected abstract void writeSetPropertyMethodBody(PrettyWriter out,
                                                     String componentClass,
                                                     Iterator properties) throws IOException;

}
