/*
 * 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.extensions.scripting.api;

import org.apache.myfaces.extensions.scripting.core.util.FileUtils;

import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Configuration class for our ext-scripting system.
 * It keeps all internal configuration data needed
 * by the various part of the system.
 * <p/>
 * It is pre initialized in our init stages
 * and later accessed only readonly.
 */

public class Configuration {

    /**
     * the source dirs per scripting engine
     */
    volatile Map<Integer, CopyOnWriteArrayList<String>> _sourceDirs = new ConcurrentHashMap<Integer, CopyOnWriteArrayList<String>>();

    /**
     * the target compile path
     */
    volatile File _compileTarget = FileUtils.getTempDir();

    /**
     * if set to true we do an initial compile step upon loading
     */
    boolean _initialCompile = true;

    /**
     * the package whitelist used by our system
     * to determine which packages are under control.
     * <p/>
     * Note an empty whitelist means, all packages with sourcedirs attached to.
     */
    Set<String> _packageWhiteList = new HashSet<String>();

    /**
     * Optional additional classpath for the compilers
     * to be able to pick up additional compile jars
     */
    List<String> _additionalClassPath = new LinkedList<String>();

    /**
     * we keep track of separate resource dirs
     * for systems which can use resource loaders
     * <p/>
     * so that we can load various resources as well
     * from separate source directories instead
     */
    volatile List<String> _resourceDirs = new CopyOnWriteArrayList<String>();

    @SuppressWarnings("unchecked")
    public Collection<String> getSourceDirs(int scriptingEngine) {
        Collection<String> retVal = _sourceDirs.get(scriptingEngine);
        if (retVal == null) return Collections.EMPTY_SET;
        return retVal;
    }

    public Collection<String> getAllSourceDirs() {
        Set<String> retVal = new HashSet(10);
        for (Map.Entry<Integer, CopyOnWriteArrayList<String>> entry : _sourceDirs.entrySet()) {
            for (String dir : entry.getValue()) {
                retVal.add(dir);
            }
        }
        return retVal;
    }

    /**
     * returns a set of whitelisted subdirs hosting the source
     *
     * @param scriptingEngine the scripting engine for which the dirs have to be determined
     *                        (note every scripting engine has a unique integer value)
     * @return the current whitelisted dirs hosting the sources
     */
    public Collection<String> getWhitelistedSourceDirs(int scriptingEngine) {
        List<String> origSourceDirs = _sourceDirs.get(scriptingEngine);
        if (_packageWhiteList.isEmpty()) {
            return origSourceDirs;
        }

        return mergeWhitelisted(origSourceDirs);
    }

    /**
     * merges the whitelisted packages with the sourcedirs and generates a final list
     * which left join of both sets - the ones which do not exist in reality
     *
     * @param origSourceDirs the original source dirs
     * @return the joined existing subset of all directories which exist
     */
    private Collection<String> mergeWhitelisted(List<String> origSourceDirs) {
        List<String> retVal = new ArrayList<String>(_packageWhiteList.size() * origSourceDirs.size() + origSourceDirs.size());

        for (String whitelisted : _packageWhiteList) {
            whitelisted = whitelisted.replaceAll("\\.", FileUtils.getFileSeparatorForRegex());
            for (String sourceDir : origSourceDirs) {
                String newSourceDir = sourceDir + File.separator + whitelisted;
                if ((new File(newSourceDir)).exists()) {
                    retVal.add(newSourceDir);
                }
            }
        }
        return retVal;
    }

    /**
     * Add a new source dir for the corresponding scripting engine
     *
     * @param scriptingEngine integer value marking the corresponding engine
     * @param sourceDir       the source directory added to the existing source dir list
     */
    public void addSourceDir(int scriptingEngine, String sourceDir) {
        CopyOnWriteArrayList<String> dirs = _sourceDirs.get(scriptingEngine);
        if (dirs == null) {
            dirs = new CopyOnWriteArrayList<String>();
            _sourceDirs.put(scriptingEngine, dirs);
        }
        dirs.add(sourceDir);
    }

    /**
     * <p>Resolves and returns a File handle that represents the class file of
     * the given class on the file system. However, note that this method only
     * returns <code>null</code> if an error occured while resolving the class
     * file. A non-null valuee doesn't necessarily mean that the class file
     * actually exists. In oder to check the existence call the according
     * method on the returned object.</p>
     *
     * @param className the name of the class that you want to resolve
     * @return a File handle that represents the class file of the given class
     *         on the file system
     * @see java.io.File#exists()
     */
    public File resolveClassFile(String className) {
        //if(className.contains("rg/apache/myfaces/javaloader/componentTest/JavaTestComponent$PropertyKeys")) {
        //    System.out.println("Debuginfo found");
        //}
        //int subClassPos = className.indexOf("$");
        //className = (subClassPos != -1)? className.substring(0, subClassPos) :className;
        return new File(getCompileTarget(),
                className.replaceAll("\\.", "/").concat(".class"));
    }

    public File getCompileTarget() {
        return _compileTarget;
    }

    public void addResourceDir(String dir) {
        _resourceDirs.add(dir);
    }

    public List<String> getResourceDirs() {
        return _resourceDirs;
    }

    public boolean isInitialCompile() {
        return _initialCompile;
    }

    public void setInitialCompile(boolean initialCompile) {
        this._initialCompile = initialCompile;
    }

    public void addWhitelistPackage(String pkg) {
        _packageWhiteList.add(pkg);
    }

    public Set<String> getPackageWhiteList() {
        return _packageWhiteList;
    }

    public void setPackageWhiteList(Set<String> packageWhiteList) {
        this._packageWhiteList = packageWhiteList;
    }

    public void addAdditionalClassPath(String path) {
        _additionalClassPath.add(path);
    }

    public List<String> getAdditionalClassPath() {
        return _additionalClassPath;
    }

    public void setAdditionalClassPath(List<String> additionalClassPath) {
        this._additionalClassPath = additionalClassPath;
    }
}
