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

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.ServerSocket;
import java.util.*;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.sling.crankstart.launcher.Launcher;
import org.apache.sling.crankstart.launcher.LauncherListener;
import org.apache.sling.crankstart.launcher.PropertiesVariableResolver;
import org.apache.sling.provisioning.model.ModelUtility.VariableResolver;
import org.junit.rules.ExternalResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** JUnit Rule that starts a Crankstart instance, using a set of provisioning
 *  models. See our integration tests for examples. 
 */
public class CrankstartSetup extends ExternalResource {
    
    private static final Logger log = LoggerFactory.getLogger(CrankstartSetup.class);
    private final int port = getAvailablePort();
    private final String storagePath = getOsgiStoragePath(); 
    private Thread crankstartThread;
    private final String baseUrl = "http://localhost:" + port;
    private final Properties replacementProps = new Properties();
    
    private static List<CrankstartSetup> toCleanup = new ArrayList<CrankstartSetup>();
    private static Thread shutdownHook;
    
    private VariableResolver variablesResolver = new PropertiesVariableResolver(replacementProps, Launcher.VARIABLE_OVERRIDE_PREFIX);
    
    private String [] classpathModelPaths;
    private boolean shutdown;
    private int bundlesStarted;
    private int bundlesFailed;
    private int totalBundles;


    @Override
    public String toString() {
        return getClass().getSimpleName() + ", port " + port + ", OSGi storage " + storagePath;
    }
    
    public CrankstartSetup() {
        synchronized (getClass()) {
            if(shutdownHook == null) {
                shutdownHook = new Thread(CrankstartSetup.class.getSimpleName() + " shutdown thread") {
                    @Override
                    public void run() {
                        log.info("Starting cleanup");
                        cleanup();
                        log.info("Cleanup done");
                    }
                };
                Runtime.getRuntime().addShutdownHook(shutdownHook);
            }
        }
    }


    public CrankstartSetup withModelResources(String ... classpathModelPaths) {
        this.classpathModelPaths = classpathModelPaths;
        return this;
    }
            
    private static int getAvailablePort() {
        int result = -1;
        ServerSocket s = null;
        try {
            try {
                s = new ServerSocket(0);
                result = s.getLocalPort();
            } finally {
                if(s != null) {
                    s.close();
                }
            }
        } catch(Exception e) {
            throw new RuntimeException("getAvailablePort failed", e);
        }
        return result;
    }
    
    private static void mergeModelResource(Launcher launcher, String path) throws Exception {
        final InputStream is = CrankstartSetup.class.getResourceAsStream(path);
        assertNotNull("Expecting test resource to be found:" + path, is);
        final Reader input = new InputStreamReader(is);
        try {
            Launcher.mergeModel(launcher.getModel(), input, path);
            launcher.computeEffectiveModel();
        } finally {
            input.close();
        }
    }
    
    public String getBaseUrl() {
        return baseUrl;
    }

    public int getBundlesFailed() {
        return bundlesFailed;
    }

    public int getBundlesStarted() {
        return bundlesStarted;
    }

    public int getTotalBundles() {
        return totalBundles;
    }

    public boolean isShutdownComplete() {
        return shutdown;
    }
    
    private static void cleanup() {
        synchronized (toCleanup) {
            if(toCleanup.isEmpty()) {
                log.info("No Crankstart instances to cleanup");
                return;
            }
            log.info("Stopping {} running Crankstart instances...", toCleanup.size());
            for(CrankstartSetup s : toCleanup) {
                s.stopCrankstartInstance();
            }
            toCleanup.clear();
        }
    }
    
    @Override
    protected void before() throws Throwable {
        if(crankstartThread != null) {
            log.debug("Already running");
            return;
        }
        
        cleanup();
        
        log.info("Starting {}", this);
        
        // Add system properties which have the expected prefix
        for(Object o : System.getProperties().keySet()) {
            final String key = o.toString();
            if(key.startsWith(Launcher.VARIABLE_OVERRIDE_PREFIX)) {
                replacementProps.setProperty(key, System.getProperty(key));
            }
        }
        
        final HttpUriRequest get = new HttpGet(baseUrl);
        replacementProps.setProperty("crankstart.model.http.port", String.valueOf(port));
        replacementProps.setProperty("crankstart.model.osgi.storage.path", storagePath);
        
        try {
            new DefaultHttpClient().execute(get);
            fail("Expecting connection to " + port + " to fail before starting HTTP service");
        } catch(IOException expected) {
        }
        shutdown = false;
        bundlesStarted = 0;
        bundlesFailed = 0;
        totalBundles = 0;
        final Launcher launcher = new Launcher().withVariableResolver(variablesResolver).withListener(new LauncherListener() {
            @Override
            public void onStartup(int started, int failed, int totalBundles) {
                CrankstartSetup.this.bundlesStarted = started;
                CrankstartSetup.this.bundlesFailed = failed;
                CrankstartSetup.this.totalBundles = totalBundles;
            }

            @Override
            public void onShutdown() {
                shutdown = true;
            }
        });
        for(String path : classpathModelPaths) {
            mergeModelResource(launcher, path);
        }
        launcher.computeEffectiveModel();
        
        crankstartThread = new Thread() {
            public void run() {
                try {
                    launcher.launch();
                } catch(InterruptedException e) {
                    log.info("Launcher thread was interrupted, exiting");
                } catch(Exception e) {
                    e.printStackTrace();
                    fail("Launcher exception:" + e);
                }
            }
        };
        crankstartThread.setDaemon(true);
        crankstartThread.start();
        
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                stopCrankstartInstance();
            }
        });
    }
    
    private void stopCrankstartInstance() {
        log.info("Stopping {}", this);
        if(crankstartThread == null) {
            return;
        }
        crankstartThread.interrupt();
        try {
            crankstartThread.join();
        } catch(InterruptedException ignore) {
        }
        crankstartThread = null;
    }
    
    private static String getOsgiStoragePath() {
        final File tmpRoot = new File(System.getProperty("java.io.tmpdir"));
        final File tmpFolder = new File(tmpRoot, CrankstartSetup.class.getSimpleName() + "_" + UUID.randomUUID());
        if(!tmpFolder.mkdir()) {
            fail("Failed to create " + tmpFolder.getAbsolutePath());
        }
        tmpFolder.deleteOnExit();
        return tmpFolder.getAbsolutePath();
    }
}