/*
 *  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.trinidadbuild.plugin.faces.generator.taglib;

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;

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


/**
 * TODO: comment this!
 *
 * @author Bruno Aranda (latest modification by $Author$)
 * @version $Revision$ $Date$
 */
public abstract class AbstractComponentTagGenerator implements ComponentTagGenerator
{
  @Override
  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);
  }


  @Override
  public void writeImports(PrettyWriter out, SourceTemplate template, String packageName,
    String fullSuperclassName, String superclassName, Collection components)
  {
    // TODO: support SourceTemplate

    Set imports = new TreeSet();

    for (Iterator<ComponentBean> lIterator = components.iterator(); lIterator.hasNext();)
    {
      ComponentBean component = lIterator.next();
      Iterator<PropertyBean> 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 = properties.next();

        String propertyClass = property.getPropertyClass();

        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);
  }

  @Override
  public void writeClassBegin(PrettyWriter out,
                              String className,
                              String superclassName,
                              ComponentBean component,
                              SourceTemplate template,
                              boolean hasTemplate)
  {
    // TODO: add support for source template

    int modifiers = component.getTagClassModifiers();

    // If there is no source template but there is a sub-class, then make the generate class
    // abstract.
    if (template == null && hasTemplate)
    {
      modifiers |= Modifier.ABSTRACT;
    }

    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();
  }


  @Override
  public void writeConstructor(PrettyWriter out,
                               ComponentBean component,
                               String overrideClassName,
                               int modifiers) throws IOException
  {
    String className;

    if (overrideClassName != null)
    {
      className = overrideClassName;
    }
    else
    {
      String fullClassName = component.getTagClass();
      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("}");
  }

  @Override
  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("}");
  }

  @Override
  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("}");
  }

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

  public void writePropertyMembers(PrettyWriter out,
                                   ComponentBean component) throws IOException
  {
    Iterator<PropertyBean> properties = component.properties();
    properties = new FilteredIterator(properties, new TagAttributeFilter());
    if (isSetterMethodFinal())
    {
      // Do not generate property methods if they are final and the properties are overrides
      properties = new FilteredIterator(properties, new NonOverriddenFilter());
    }

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

  /**
   * Whether the tag setter methods have the final modifier
   *
   * @return true if the setter methods are final
   */
  protected boolean isSetterMethodFinal()
  {
    return false;
  }

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

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


  @Override
  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());
    properties = new FilteredIterator(properties, new NonOverriddenFilter());

    if (properties.hasNext() || special)
    {
      out.println();
      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;

  protected static class NonOverriddenFilter
    extends PropertyFilter
  {
    protected boolean accept(
      PropertyBean property)
    {
      return (!property.isOverride());
    }
  }
}
