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

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

import org.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 class UtilJavaParse {

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

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

    // FIXME: Not thread safe
    public static Set<String> serviceMethodNames = 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");
    }
    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;
    }

    // FIXME: Not thread safe
    public static Set<String> entityMethodNames = new HashSet<String>();
    static {
        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");
    }
    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();
    }
}
