/*
 * 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.sling.crankstart.launcher;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Callable;

import org.apache.sling.provisioning.model.Artifact;
import org.apache.sling.provisioning.model.ArtifactGroup;
import org.apache.sling.provisioning.model.Feature;
import org.apache.sling.provisioning.model.Model;
import org.apache.sling.provisioning.model.ModelUtility;
import org.apache.sling.provisioning.model.ModelUtility.VariableResolver;
import org.apache.sling.provisioning.model.RunMode;
import org.apache.sling.provisioning.model.io.ModelReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Launch an OSGi app instance using the Sling provisioning model */
public class Launcher {
    private Model model = new Model();
    private static final Logger log = LoggerFactory.getLogger(Launcher.class);
    
    public static final String CRANKSTART_FEATURE = ":crankstart";
    public static final String MODEL_KEY = "model";
    public static final String LISTENER_KEY = "listener";
    public static final String FRAMEWORK_KEY = "framework";
    
    public static final String VARIABLE_OVERRIDE_PREFIX = "crankstart.model.";

    /** Default variable resolver using system properties */
    public static final VariableResolver DEFAULT_VARIABLE_RESOLVER = 
        new PropertiesVariableResolver(System.getProperties(), VARIABLE_OVERRIDE_PREFIX) {
            @Override
            protected void onOverride(String variableName, String value, String propertyName) {
                log.info("Overriding model variable {}={} (from system property {})", variableName, value, propertyName);
            }
        };
    
    /** Allow for overriding model variables */ 
    private VariableResolver variableResolver; 
    
    public static final FeatureFilter NOT_CRANKSTART_FILTER = new FeatureFilter() {
        @Override
        public boolean ignoreFeature(Feature f) {
            return Launcher.CRANKSTART_FEATURE.equals(f.getName());
        }
    };
    
    public static final FeatureFilter ONLY_CRANKSTART_FILTER = new FeatureFilter() {
        @Override
        public boolean ignoreFeature(Feature f) {
            return !Launcher.CRANKSTART_FEATURE.equals(f.getName());
        }
    };
    private LauncherListener listener;

    public Launcher(String ... args) throws Exception {
        MavenResolver.setup();
        withVariableResolver(null);
        withModelPaths(args);
    }
    
    /** Use the supplied VariableResolver. Defaults to DEFAULT_VARIABLE_RESOLVER if v
     *  is null or if this is not called. 
     */
    public Launcher withVariableResolver(VariableResolver v) {
        variableResolver = (v == null ? DEFAULT_VARIABLE_RESOLVER : v);
        return this;
    }

    public Launcher withListener(LauncherListener listener) {
        this.listener = listener;
        return this;
    }

    /** Add models from the supplied paths, can be either files or folders */ 
    public Launcher withModelPaths(String ... paths) throws Exception {
        // Find all files to read and sort the list, to be deterministic
        final SortedSet<File> toRead = new TreeSet<File>();
        
        for(String name : paths) {
            final File f = new File(name);
            if(f.isDirectory()) {
                final String [] list = f.list();
                for(String s : list) {
                    toRead.add(new File(f, s));
                }
            } else {
                toRead.add(f);
            }
        }

        // Merge all model files 
        for(File f : toRead) {
            mergeModel(f);
        }
        
        computeEffectiveModel();
        return this;
    }
    
    public void computeEffectiveModel() throws Exception {
        new NestedModelsMerger(model).visit();
        model = ModelUtility.getEffectiveModel(model, variableResolver);
    }
    
    public Model getModel() {
        return model;
    }
    
    /** Can be called before launch() to read and merge additional models.
     *  @param r provisioning model to read, closed by this method after reading */ 
    public static void mergeModel(Model mergeInto, Reader r, String sourceInfo) throws IOException {
        log.info("Merging provisioning model {}", sourceInfo);
        try {
            final Model m = ModelReader.read(r, sourceInfo);
            ModelUtility.merge(mergeInto, m);
        } finally {
            r.close();
        }
    }
    
    /** Can be called before launch() to read and merge additional models */
    public void mergeModel(File f) throws IOException {
        mergeModel(model, new BufferedReader(new FileReader(f)), f.getAbsolutePath());
    }
    
    public void launch() throws Exception {
        // Setup initial classpath to launch the OSGi framework
        for(URL u : getClasspathURLs(model, CRANKSTART_FEATURE)) {
            addToClasspath(u);
        }

        // Need to load FrameworkSetup in this way to avoid any static references to OSGi classes in this class, as those are
        // not available yet when this class is loaded.
        final Callable<?> c = (Callable<?>) getClass().getClassLoader().loadClass("org.apache.sling.crankstart.launcher.FrameworkSetup").newInstance();
        @SuppressWarnings("unchecked") final Map<String, Object> cmap = (Map<String, Object>)c; 
        cmap.put(MODEL_KEY, model);
        cmap.put(LISTENER_KEY, listener);
        c.call();
    }
    
    /** Slightly hacky way to add URLs to the system classloader,
     *  based on http://stackoverflow.com/questions/60764/how-should-i-load-jars-dynamically-at-runtime
     */  
    private void addToClasspath(URL u) throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        final URLClassLoader sysLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
        final Method m = URLClassLoader.class.getDeclaredMethod("addURL",new Class[]{URL.class});
        m.setAccessible(true);
        m.invoke(sysLoader,new Object[]{ u });
        log.info("Added to classpath: {}", u);
    }
    
    /** Convert a Model feature to a set of URLs meant to setup
     *  an URLClassLoader.
     */
    List<URL> getClasspathURLs(Model m, String featureName) throws MalformedURLException {
        final List<URL> result = new ArrayList<URL>();
        
        // Add all URLs from the special feature to our classpath
        final Feature f = m.getFeature(featureName);
        if(f == null) {
            log.warn("No {} feature found in provisioning model, nothing to add to our classpath", featureName);
        } else {
            for(RunMode rm : f.getRunModes()) {
                for(ArtifactGroup g : rm.getArtifactGroups()) {
                    for(Artifact a : g) {
                        final String url = MavenResolver.mvnUrl(a);
                        try {
                            result.add(new URL(url));
                        } catch(MalformedURLException e) {
                            final MalformedURLException up = new MalformedURLException("Invalid URL [" + url + "]");
                            up.initCause(e);
                            throw up;
                        }
                    }
                }
            }
        }
        return result;
    }
    
     public static void main(String [] args) throws Exception {
        if(args.length < 1) {
            System.err.println("Usage: " + Launcher.class.getSimpleName() + " provisioning-model [provisioning-model ...]"); 
            System.err.println("Where provisioning-model is either a Sling provisioning model file");
            System.err.println("or a folder that contains several of those.");
            System.exit(0);
        }
        
        new Launcher(args).launch();
    }
}
