/*******************************************************************************
 * 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.container;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.ofbiz.base.component.ComponentConfig;
import org.apache.ofbiz.base.component.ComponentException;
import org.apache.ofbiz.base.component.ComponentLoaderConfig;
import org.apache.ofbiz.base.start.Classpath;
import org.apache.ofbiz.base.start.Start;
import org.apache.ofbiz.base.start.StartupCommand;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.FileUtil;

/**
 * ComponentContainer - StartupContainer implementation for Components
 *
 * The purpose of this container is to load the classpath for all components
 * defined in OFBiz. This container must run before any other containers to
 * allow components to access any necessary resources. Furthermore, the
 * ComponentContainer also builds up the <code>ComponentConfigCache</code>
 * defined in <code>ComponentConfig</code> to keep track of loaded components
 *
 */
public class ComponentContainer implements Container {

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

    private String name;
    private final AtomicBoolean loaded = new AtomicBoolean(false);
    private final List<Classpath> componentsClassPath = new ArrayList<Classpath>();

    @Override
    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
        if (!loaded.compareAndSet(false, true)) {
            throw new ContainerException("Components already loaded, cannot start");
        }
        this.name = name;

        // load the components from framework/base/config/component-load.xml (root components)
        try {
            for (ComponentLoaderConfig.ComponentDef def: ComponentLoaderConfig.getRootComponents()) {
                loadComponentFromConfig(Start.getInstance().getConfig().ofbizHome, def);
            }
        } catch (IOException | ComponentException e) {
            throw new ContainerException(e);
        }
        loadClassPathForAllComponents(componentsClassPath);
        Debug.logInfo("All components loaded", module);
    }

    /**
     * @see org.apache.ofbiz.base.container.Container#start()
     */
    public boolean start() throws ContainerException {
        return loaded.get();
    }

    /**
     * Iterate over all the components and load their classpath URLs into the classloader
     * and set the classloader as the context classloader
     *
     * @param componentsClassPath: a list of classpaths for all components
     * @throws ContainerException
     */
    private void loadClassPathForAllComponents(List<Classpath> componentsClassPath) throws ContainerException {
        List<URL> allComponentUrls = new ArrayList<URL>();
        for(Classpath classPath : componentsClassPath) {
            try {
                allComponentUrls.addAll(Arrays.asList(classPath.getUrls()));
            } catch (MalformedURLException e) {
                Debug.logError("Unable to load component classpath" + classPath.toString(), module);
                Debug.logError(e.getMessage(), module);
            }
        }
        URL[] componentURLs = allComponentUrls.toArray(new URL[allComponentUrls.size()]);
        URLClassLoader classLoader = new URLClassLoader(componentURLs, Thread.currentThread().getContextClassLoader());
        Thread.currentThread().setContextClassLoader(classLoader);
    }

    /**
     * Checks if <code>ComponentDef.type</code> is a directory or a single component.
     * If it is a directory, load the directory, otherwise load a single component
     *
     * @param parentPath: the parent path of what is being loaded
     * @param def: the component or directory loader definition
     * @throws IOException
     */
    private void loadComponentFromConfig(String parentPath, ComponentLoaderConfig.ComponentDef def) throws IOException {
        String location = def.location.startsWith("/") ? def.location : parentPath + "/" + def.location;

        if (def.type.equals(ComponentLoaderConfig.ComponentType.COMPONENT_DIRECTORY)) {
            loadComponentDirectory(location);
        } else if (def.type.equals(ComponentLoaderConfig.ComponentType.SINGLE_COMPONENT)) {
            ComponentConfig config = retrieveComponentConfig(def.name, location);
            if (config != null) {
                loadComponent(config);
            }
        }
    }

    /**
     * Checks to see if the directory contains a load file (component-load.xml) and
     * then delegates loading to the appropriate method
     *
     * @param directoryName: the name of component directory to load
     * @throws IOException
     */
    private void loadComponentDirectory(String directoryName) throws IOException {
        Debug.logInfo("Auto-Loading component directory : [" + directoryName + "]", module);

        File directoryPath = FileUtil.getFile(directoryName);
        if (directoryPath.exists() && directoryPath.isDirectory()) {
            File componentLoadFile = new File(directoryPath, ComponentLoaderConfig.COMPONENT_LOAD_XML_FILENAME);
            if (componentLoadFile != null && componentLoadFile.exists()) {
                loadComponentsInDirectoryUsingLoadFile(directoryPath, componentLoadFile);
            } else {
                loadComponentsInDirectory(directoryPath);
            }
        } else {
            Debug.logError("Auto-Load Component directory not found : " + directoryName, module);
        }

    }

    /**
     * load components residing in a directory only if they exist in the component
     * load file (component-load.xml) and they are sorted in order from top to bottom
     * in the load file
     *
     * @param directoryPath: the absolute path of the directory
     * @param componentLoadFile: the name of the load file (i.e. component-load.xml)
     * @throws IOException
     */
    private void loadComponentsInDirectoryUsingLoadFile(File directoryPath, File componentLoadFile) throws IOException {
        URL configUrl = null;
        try {
            configUrl = componentLoadFile.toURI().toURL();
            List<ComponentLoaderConfig.ComponentDef> componentsToLoad = ComponentLoaderConfig.getComponentsFromConfig(configUrl);
            if (componentsToLoad != null) {
                for (ComponentLoaderConfig.ComponentDef def: componentsToLoad) {
                    loadComponentFromConfig(directoryPath.toString(), def);
                }
            }
        } catch (MalformedURLException e) {
            Debug.logError(e, "Unable to locate URL for component loading file: " + componentLoadFile.getAbsolutePath(), module);
        } catch (ComponentException e) {
            Debug.logError(e, "Unable to load components from URL: " + configUrl.toExternalForm(), module);
        }
    }

    /**
     * Load all components in a directory because it does not contain 
     * a load-components.xml file. The components are sorted alphabetically
     * for loading purposes
     *
     * @param directoryPath: the absolute path of the directory
     * @throws IOException
     */
    private void loadComponentsInDirectory(File directoryPath) throws IOException {
        String[] sortedComponentNames = directoryPath.list();
        Arrays.sort(sortedComponentNames);

        for (String componentName: sortedComponentNames) {
            File componentPath = FileUtil.getFile(directoryPath.getCanonicalPath() + File.separator + componentName);
            String componentLocation = componentPath.getCanonicalPath();
            File configFile = FileUtil.getFile(componentLocation.concat(File.separator).concat(ComponentConfig.OFBIZ_COMPONENT_XML_FILENAME));

            if (componentPath.isDirectory() && !componentName.startsWith(".") && configFile.exists()) {
                ComponentConfig config = retrieveComponentConfig(null, componentLocation);
                if (config != null) { 
                    loadComponent(config);
                }
            }
        }
    }

    /**
     * Fetch the <code>ComponentConfig</code> for a certain component
     *
     * @param name: component name
     * @param location: directory location of the component
     * @return The component configuration
     */
    private ComponentConfig retrieveComponentConfig(String name, String location) {
        ComponentConfig config = null;
        try {
            config = ComponentConfig.getComponentConfig(name, location);
        } catch (ComponentException e) {
            Debug.logError("Cannot load component : " + name + " @ " + location + " : " + e.getMessage(), module);
        }
        if (config == null) {
            Debug.logError("Cannot load component : " + name + " @ " + location, module);
        }
        return config;
    }

    /**
     * Load a single component by adding all its classpath entries to
     * the list of classpaths to be loaded
     *
     * @param config: the component configuration
     * @throws IOException
     */
    private void loadComponent(ComponentConfig config) throws IOException {
        if (config.enabled()) {
            Classpath classpath = buildClasspathFromComponentConfig(config);
            componentsClassPath.add(classpath);
            Debug.logInfo("Added class path for component : [" + config.getComponentName() + "]", module);
        } else {
            Debug.logInfo("Not loading component [" + config.getComponentName() + "] because it is disabled", module);
        }
    }

    /**
     * Construct a <code>Classpath</code> object for a certain component based
     * on its configuration defined in <code>ComponentConfig</code>
     *
     * @param config: the component configuration
     * @return the constructed classpath
     * @throws IOException
     */
    private Classpath buildClasspathFromComponentConfig(ComponentConfig config) throws IOException {
        Classpath classPath = new Classpath();
        String configRoot = config.getRootLocation().replace('\\', '/');
        configRoot = configRoot.endsWith("/") ? configRoot : configRoot + "/";
        List<ComponentConfig.ClasspathInfo> classpathInfos = config.getClasspathInfos();

        for (ComponentConfig.ClasspathInfo cp: classpathInfos) {
            String location = cp.location.replace('\\', '/');
            if (!"jar".equals(cp.type) && !"dir".equals(cp.type)) {
                Debug.logError("Classpath type '" + cp.type + "' is not supported; '" + location + "' not loaded", module);
                continue;
            }

            location = location.startsWith("/") ? location.substring(1) : location;
            String dirLoc = location.endsWith("/*") ? location.substring(0, location.length() - 2) : location; 
            File path = FileUtil.getFile(configRoot + dirLoc);

            if (path.exists()) {
                classPath.addComponent(configRoot + location);
                if (path.isDirectory() && "dir".equals(cp.type)) {
                    classPath.addFilesFromPath(path);
                }
            } else {
                Debug.logWarning("Location '" + configRoot + dirLoc + "' does not exist", module);
            }
        }
        return classPath;
    }
    /**
     * @see org.apache.ofbiz.base.container.Container#stop()
     */
    public void stop() throws ContainerException {
    }

    public String getName() {
        return name;
    }

}
