/*
 * 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.ofbiz.base.util;

import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.ofbiz.base.component.ComponentConfig;


/**
 * Java Source Parsing Utilities
 *
 * NOTE: the approach here is not the best and it may be better to use a parser, line one based on antlr, or using a Java Bytecode parser to look at .class files.
 *
 */
public final class UtilJavaParse {

    public static final String module = UtilJavaParse.class.getName();

    // FIXME: Not thread safe
    private static Set<String> serviceMethodNames = new HashSet<String>();
    private static Set<String> entityMethodNames = new HashSet<String>();
    static {
        serviceMethodNames.add("runSync");
        serviceMethodNames.add("runSyncIgnore");
        serviceMethodNames.add("runAsync");
        serviceMethodNames.add("runAsyncWait");
        serviceMethodNames.add("registerCallback");
        serviceMethodNames.add("schedule"); // NOTE: the service name may be the 1st, 2nd or 3rd param for variations on this
        serviceMethodNames.add("addRollbackService");
        serviceMethodNames.add("addCommitService");
        
        entityMethodNames.add("getModelEntity");
        entityMethodNames.add("getEntityGroupName");
        entityMethodNames.add("getModelEntityMapByGroup");
        entityMethodNames.add("getGroupHelperName");
        entityMethodNames.add("getEntityHelperName");
        entityMethodNames.add("getEntityHelper");

        entityMethodNames.add("makeValue");
        entityMethodNames.add("makeValueSingle");
        entityMethodNames.add("makeValidValue");
        entityMethodNames.add("makePK");
        entityMethodNames.add("makePKSingle");

        entityMethodNames.add("create");
        entityMethodNames.add("createSingle");
        entityMethodNames.add("removeByAnd");
        entityMethodNames.add("removeByCondition");

        entityMethodNames.add("create");
        entityMethodNames.add("createSingle");
        entityMethodNames.add("removeByAnd");
        entityMethodNames.add("removeByCondition");
        entityMethodNames.add("storeByCondition");
        entityMethodNames.add("removeAll");
        entityMethodNames.add("findOne");
        entityMethodNames.add("findByPrimaryKey");
        entityMethodNames.add("findByPrimaryKeyCache");
        entityMethodNames.add("findAllCache");
        entityMethodNames.add("findByAnd");
        entityMethodNames.add("findByOr");
        entityMethodNames.add("findByAndCache");
        entityMethodNames.add("findByLike");
        entityMethodNames.add("findByCondition");
        entityMethodNames.add("findByConditionCache");
        entityMethodNames.add("findListIteratorByCondition");
        entityMethodNames.add("find");
        entityMethodNames.add("findList");
        entityMethodNames.add("findCountByAnd");
        entityMethodNames.add("findCountByCondition");
    }

    private UtilJavaParse () {}

    public static String findRealPathAndFileForClass(String fullyQualifiedClassName) {
        // search through the component directories, in the src directory for each, using the class path as the path within it

        String sourceSubPath = fullyQualifiedClassName.substring(0, fullyQualifiedClassName.lastIndexOf(".")).replace('.', File.separatorChar);
        String classFileName = fullyQualifiedClassName.substring(fullyQualifiedClassName.lastIndexOf(".")+1) + ".java";

        Collection<ComponentConfig> allComponentConfigs = ComponentConfig.getAllComponents();
        for (ComponentConfig cc: allComponentConfigs) {
            String rootDirectory = cc.getRootLocation();
            if (!rootDirectory.endsWith(File.separatorChar + "")) rootDirectory += File.separatorChar;
            rootDirectory += "src" + File.separatorChar;

            File rootDirFile = new File(rootDirectory);
            if (!rootDirFile.exists()) {
                // no src directory, move along
                continue;
            }

            String classDir = rootDirectory + sourceSubPath;
            File classDirFile = new File(classDir);
            if (!classDirFile.exists()) {
                // no src class sub-directory, move along
                continue;
            }

            String fullPathAndFile = classDir + File.separatorChar + classFileName;
            File classFile = new File(fullPathAndFile);
            if (classFile.exists()) {
                if (Debug.verboseOn()) Debug.logVerbose("In findRealPathAndFileForClass for [" + fullyQualifiedClassName + "]: [" + fullPathAndFile + "]", module);
                return fullPathAndFile;
            }
        }

        return null;
    }

    public static int findServiceMethodBlockStart(String methodName, String javaFile) {
        if (Debug.verboseOn()) Debug.logVerbose("In findServiceMethodBlockStart for " + methodName, module);

        // starts with something like this: public static Map exportServiceEoModelBundle(DispatchContext dctx, Map context) {

        // start with the main pattern
        int methodNameIndex = javaFile.indexOf("public static Map " + methodName + "(DispatchContext dctx, Map context) {");
        // try a little less... and some nice messy variations...
        if (methodNameIndex < 0) methodNameIndex = javaFile.indexOf(" Map " + methodName + "(DispatchContext ");
        if (methodNameIndex < 0) methodNameIndex = javaFile.indexOf(" Map  " + methodName + "(DispatchContext ");
        if (methodNameIndex < 0) methodNameIndex = javaFile.indexOf(" Map " + methodName + " (DispatchContext ");
        if (methodNameIndex < 0) methodNameIndex = javaFile.indexOf(" Map " + methodName + "(DispatchContext ");
        if (methodNameIndex < 0) methodNameIndex = javaFile.indexOf(" Map " + methodName + " (DispatchContext ");

        // not found!
        if (methodNameIndex < 0) return -1;

        // find the open brace and return its position
        return javaFile.indexOf("{", methodNameIndex);
    }

    public static int findEndOfBlock(int blockStart, String javaFile) {
        //Debug.logInfo("In findEndOfBlock for blockStart " + blockStart, module);

        int nextOpen = javaFile.indexOf("{", blockStart+1);
        int nextClose = javaFile.indexOf("}", blockStart+1);
        if (nextOpen > 0 && nextClose > 0 && nextClose > nextOpen) {
            javaFile.substring(nextOpen, nextClose);
        }
        // if no close, end with couldn't find
        if (nextClose < 0) return -1;
        // while nextOpen is found and is before the next close, then recurse (list
        while (nextOpen > -1 && nextOpen < nextClose) {
            int endOfSubBlock = findEndOfBlock(nextOpen, javaFile);
            if (endOfSubBlock < 0) return -1;
            nextOpen = javaFile.indexOf("{", endOfSubBlock+1);
            nextClose = javaFile.indexOf("}", endOfSubBlock+1);
            //Debug.logInfo("In loop in findEndOfBlock for nextOpen=" + nextOpen + ", nextClose=" + nextClose + ", endOfSubBlock=" + endOfSubBlock, module);
        }

        // at this point there should be no nextOpen or nextOpen is after the nextClose, meaning we're at the end of the block
        return nextClose;
    }

    public static Set<String> findServiceCallsInBlock(int blockStart, int blockEnd, String javaFile) {
        Set<String> serviceNameSet = new HashSet<String>();

        int dispatcherIndex = javaFile.indexOf("dispatcher.", blockStart+1);
        while (dispatcherIndex > 0 && dispatcherIndex < blockEnd) {
            // verify it is a call we're looking for
            int openParenIndex = javaFile.indexOf("(", dispatcherIndex);
            String curMethodName = javaFile.substring(dispatcherIndex + 11, openParenIndex).trim();
            if (serviceMethodNames.contains(curMethodName)) {
                // find the service name
                int openQuoteIndex = javaFile.indexOf("\"", openParenIndex);
                int closeQuoteIndex = javaFile.indexOf("\"", openQuoteIndex+1);
                if (openQuoteIndex - openParenIndex <= 3 && openQuoteIndex >= 0 && closeQuoteIndex >= 0) {
                    //more than two spaces/chars between quote and open paren... consider it something other than what we are looking for
                    String serviceName = javaFile.substring(openQuoteIndex+1, closeQuoteIndex).trim();
                    //Debug.logInfo("In findServiceCallsInBlock found serviceName [" + serviceName + "]", module);
                    serviceNameSet.add(serviceName);
                }
            }

            dispatcherIndex = javaFile.indexOf("dispatcher.", openParenIndex);
        }

        return serviceNameSet;
    }

    public static Set<String> findEntityUseInBlock(int blockStart, int blockEnd, String javaFile) {
        Set<String> entityNameSet = new HashSet<String>();

        int delegatorIndex = javaFile.indexOf("delegator.", blockStart+1);
        while (delegatorIndex > 0 && delegatorIndex < blockEnd) {
            // verify it is a call we're looking for
            int openParenIndex = javaFile.indexOf("(", delegatorIndex);
            String curMethodName = javaFile.substring(delegatorIndex + 10, openParenIndex).trim();
            if (entityMethodNames.contains(curMethodName)) {
                // find the entity name
                int openQuoteIndex = javaFile.indexOf("\"", openParenIndex);
                int closeQuoteIndex = javaFile.indexOf("\"", openQuoteIndex+1);
                if (openQuoteIndex - openParenIndex <= 3 && openQuoteIndex >= 0 && closeQuoteIndex >= 0) {
                    //more than two spaces/chars between quote and open paren... consider it something other than what we are looking for
                    String entityName = javaFile.substring(openQuoteIndex+1, closeQuoteIndex).trim();
                    //Debug.logInfo("In findServiceCallsInBlock found valid entityName [" + entityName + "]", module);
                    entityNameSet.add(entityName);
                }
            }

            delegatorIndex = javaFile.indexOf("delegator.", openParenIndex);
        }

        return entityNameSet;
    }

    public static String stripComments(String javaFile) {
        StringBuilder strippedFile = new StringBuilder();
        int commentOpen = javaFile.indexOf("/*");
        int commentClose = javaFile.indexOf("*/");
        if (commentOpen > -1) {
            if (commentOpen > 0) {
                strippedFile.append(javaFile.substring(0, commentOpen));
            }
            commentOpen = javaFile.indexOf("/*", commentClose);
            while (commentOpen > -1) {
                strippedFile.append(javaFile.substring(commentClose + 2, commentOpen));
                commentClose = javaFile.indexOf("*/", commentOpen);
                commentOpen = javaFile.indexOf("/*", commentClose);
            }
            strippedFile.append(javaFile.substring(commentClose + 2));
        } else {
            strippedFile.append(javaFile);
        }

        String lineSeparator = System.getProperty("line.separator");
        int lineComment = strippedFile.indexOf("//");
        while (lineComment > -1) {
            int endOfLine = strippedFile.indexOf(lineSeparator, lineComment);
            strippedFile.delete(lineComment, endOfLine);
            lineComment = strippedFile.indexOf("//", lineComment);
        }
        return strippedFile.toString();
    }
}
