/**
 * 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.activemq.openwire.generator;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.FixCRLF;
import org.codehaus.jam.JAnnotation;
import org.codehaus.jam.JClass;
import org.codehaus.jam.JProperty;
import org.codehaus.jam.JamClassIterator;

/**
 *
 */
public abstract class MultiSourceGenerator extends OpenWireGenerator {

    protected Set<String> manuallyMaintainedClasses = new HashSet<String>();
    protected File destDir;
    protected File destFile;

    protected JClass jclass;
    protected JClass superclass;
    protected String simpleName;
    protected String className;
    protected String baseClass;
    protected StringBuffer buffer;

    protected String targetDir;

    public MultiSourceGenerator() {
        initialiseManuallyMaintainedClasses();
    }

    public Object run() {
        if (destDir == null) {
            throw new IllegalArgumentException("No destDir defined!");
        }
        System.out.println(getClass().getName() + " generating files in: " + destDir);
        destDir.mkdirs();
        buffer = new StringBuffer();

        JamClassIterator iter = getClasses();
        while (iter.hasNext()) {
            try {
                jclass = iter.nextClass();
                if (isValidClass(jclass)) {
                    processClass(jclass);
                }
            } catch (Exception e) {
                System.err.println("Unable to process: " + jclass);
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * Returns all the valid properties available on the current class
     */
    public List<JProperty> getProperties() {
        List<JProperty> answer = new ArrayList<JProperty>();
        JProperty[] properties = jclass.getDeclaredProperties();
        for (int i = 0; i < properties.length; i++) {
            JProperty property = properties[i];
            if (isValidProperty(property)) {
                answer.add(property);
            }
        }
        return answer;
    }

    protected boolean isValidClass(JClass jclass) {
        JAnnotation annotation = jclass.getAnnotation("openwire:marshaller");
        if (annotation == null) {
            return false;
        }

        if (!includeInThisVersion(annotation)) {
            return false;
        }

        return !manuallyMaintainedClasses.contains(jclass.getSimpleName());
    }

    protected void processClass(JClass jclass) {
        simpleName = jclass.getSimpleName();
        superclass = jclass.getSuperclass();

        System.out.println(getClass().getName() + " processing class: " + simpleName);

        className = getClassName(jclass);
        destFile = new File(destDir, className + filePostFix);
        baseClass = getBaseClassName(jclass);

        PrintWriter out = null;
        try {
            out = new PrintWriter(new FileWriter(destFile));
            generateFile(out);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (out != null) {
                out.close();
            }
        }

        // Use the FixCRLF Ant Task to make sure the file has consistent
        // newlines so that SVN does not complain on checkin.
        Project project = new Project();
        project.init();
        FixCRLF fixCRLF = new FixCRLF();
        fixCRLF.setProject(project);
        fixCRLF.setSrcdir(destFile.getParentFile());
        fixCRLF.setIncludes(destFile.getName());
        fixCRLF.execute();
    }

    protected abstract void generateFile(PrintWriter out) throws Exception;

    protected String getBaseClassName(JClass jclass) {
        String answer = "BaseDataStructure";
        if (superclass != null) {
            String name = superclass.getSimpleName();
            if (name != null && !name.equals("Object")) {
                answer = name;
            }
        }
        return answer;
    }

    protected String getClassName(JClass jclass) {
        return jclass.getSimpleName();
    }

    public boolean isAbstractClass() {
        return jclass != null && jclass.isAbstract();
    }

    public String getAbstractClassText() {
        return isAbstractClass() ? "abstract " : "";
    }

    public boolean isMarshallerAware() {
        return isMarshallAware(jclass);
    }

    protected void initialiseManuallyMaintainedClasses() {
        String[] names = {
            "OpenWireDestination",
            "OpenWireTempDestination",
            "OpenWireQueue",
            "OpenWireTopic",
            "OpenWireTempQueue",
            "OpenWireTempTopic",
            "OpenWireMessage",
            "OpenWireTextMessage",
            "OpenWireMapMessage",
            "OpenWireBytesMessage",
            "OpenWireStreamMessage",
            "OpenWireBlobMessage",
            "OpenWireObjectMessage",
            "BaseCommand",
            "DataStructureSupport",
            "WireFormatInfo"
        };

        for (int i = 0; i < names.length; i++) {
            manuallyMaintainedClasses.add(names[i]);
        }
    }

    public String getBaseClass() {
        return baseClass;
    }

    public void setBaseClass(String baseClass) {
        this.baseClass = baseClass;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public File getDestDir() {
        return destDir;
    }

    public void setDestDir(File destDir) {
        this.destDir = destDir;
    }

    public File getDestFile() {
        return destFile;
    }

    public void setDestFile(File destFile) {
        this.destFile = destFile;
    }

    public JClass getJclass() {
        return jclass;
    }

    public void setJclass(JClass jclass) {
        this.jclass = jclass;
    }

    public Set<String> getManuallyMaintainedClasses() {
        return manuallyMaintainedClasses;
    }

    public void setManuallyMaintainedClasses(Set<String> manuallyMaintainedClasses) {
        this.manuallyMaintainedClasses = manuallyMaintainedClasses;
    }

    public String getSimpleName() {
        return simpleName;
    }

    public void setSimpleName(String simpleName) {
        this.simpleName = simpleName;
    }

    public JClass getSuperclass() {
        return superclass;
    }

    public void setSuperclass(JClass superclass) {
        this.superclass = superclass;
    }

    public String getTargetDir() {
        return targetDir;
    }

    public void setTargetDir(String sourceDir) {
        this.targetDir = sourceDir;
    }
}
