/*
 * 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.karaf.shell.dev.watch;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import org.ops4j.pax.url.maven.commons.MavenConfiguration;
import org.ops4j.pax.url.maven.commons.MavenConfigurationImpl;
import org.ops4j.pax.url.maven.commons.MavenRepositoryURL;
import org.ops4j.pax.url.mvn.ServiceConstants;
import org.ops4j.pax.url.mvn.internal.Parser;
import org.ops4j.util.property.DictionaryPropertyResolver;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.packageadmin.PackageAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Runnable singleton which watches at the defined location for bundle updates.
 */
public class BundleWatcher implements Runnable, BundleListener {

    private final Logger logger = LoggerFactory.getLogger(BundleWatcher.class);

    private BundleContext bundleContext;
    private ConfigurationAdmin configurationAdmin;

    private AtomicBoolean running = new AtomicBoolean(false);
    private long interval = 1000L;
    private List<String> watchURLs = new CopyOnWriteArrayList<String>();
    private AtomicInteger counter = new AtomicInteger(0);


    /**
     * Constructor
     */
    public BundleWatcher() {
    }

    public void bundleChanged(BundleEvent event) {
        if (event.getType() == BundleEvent.INSTALLED
                || event.getType() == BundleEvent.UNINSTALLED) {
            counter.incrementAndGet();
        }
    }

    public void run() {
        logger.debug("Bundle watcher thread started");
        int oldCounter = -1;
        Set<Bundle> watchedBundles = new HashSet<Bundle>();
        while (running.get() && watchURLs.size()>0) {
            if (oldCounter != counter.get()) {
                oldCounter = counter.get();
                watchedBundles.clear();
                for (String bundleURL : watchURLs) {
                    for (Bundle bundle : getBundlesByURL(bundleURL)) {
                        watchedBundles.add(bundle);
                    }
                }
            }
            if (watchedBundles.size()>0) {
                File localRepository = getLocalRepository();
                List<Bundle> updated = new ArrayList<Bundle>();
                for (Bundle bundle : watchedBundles) {
                    try {
                        File location = getBundleExternalLocation(localRepository, bundle);
                        if (location != null
                                && location.exists()
                                && location.lastModified() > bundle.getLastModified())
                        {
                            InputStream is = new FileInputStream(location);
                            try {
                                logger.info("[Watch] Updating watched bundle: " + bundle.getSymbolicName() + " (" + bundle.getVersion() + ")");
                                System.out.println("[Watch] Updating watched bundle: " + bundle.getSymbolicName() + " (" + bundle.getVersion() + ")");
                                bundle.update(is);
                                updated.add(bundle);
                            } finally {
                                is.close();
                            }
                        }
                    } catch (IOException ex) {
                        logger.error("Error watching bundle.", ex);
                    } catch (BundleException ex) {
                        logger.error("Error updating bundle.", ex);
                    }
                }
                ServiceReference ref = null;
                try {
                    ref = getBundleContext().getServiceReference(PackageAdmin.class.getName());
                    PackageAdmin pa = (PackageAdmin) getBundleContext().getService(ref);
                    pa.refreshPackages(updated.toArray(new Bundle[updated.size()]));
                } finally {
                    if (ref != null) {
                        getBundleContext().ungetService(ref);
                    }
                }
            }
            try {
                Thread.sleep(interval);
            } catch (InterruptedException ex) {
                running.set(false);
            }
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Bundle watcher thread stopped");
        }
    }

    /**
     * Adds a Bundle URLs to the watch list.
     * @param url
     */
    public void add(String url) {
        boolean shouldStart = running.get() && (watchURLs.size()==0);
        if (!watchURLs.contains(url)) {
            watchURLs.add(url);
            counter.incrementAndGet();
        }
        if (shouldStart) {
            Thread thread = new Thread(this);
            thread.start();
        }
    }

    /**
     * Removes a bundle URLs from the watch list.
     * @param url
     */
    public void remove(String url) {
        watchURLs.remove(url);
        counter.incrementAndGet();
    }

    /**
     * Returns the location of the Bundle inside the local maven repository.
     * @param bundle
     * @return
     */
    public File getBundleExternalLocation(File localRepository, Bundle bundle) {
        try {
            Parser p = new Parser(bundle.getLocation().substring(4));
            return new File(localRepository.getPath() + File.separator + p.getArtifactPath());
        } catch (MalformedURLException e) {
            logger.error("Could not parse artifact path for bundle" + bundle.getSymbolicName(), e);
        }
        return null;
    }

    public File getLocalRepository() {
        // Attempt to retrieve local repository location from MavenConfiguration
        MavenConfiguration configuration = retrieveMavenConfiguration();
        if (configuration != null) {
            MavenRepositoryURL localRepositoryURL = configuration.getLocalRepository();
            if (localRepositoryURL != null) {
                return localRepositoryURL.getFile().getAbsoluteFile();
            }
        }
        // If local repository not found assume default.
        String localRepo = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository";
        return new File(localRepo).getAbsoluteFile();
    }

    protected MavenConfiguration retrieveMavenConfiguration() {
        MavenConfiguration mavenConfiguration = null;
        try {
            Configuration configuration = configurationAdmin.getConfiguration(ServiceConstants.PID);
            if (configuration != null) {
                Dictionary dictonary = configuration.getProperties();
                if (dictonary != null) {
                    DictionaryPropertyResolver resolver = new DictionaryPropertyResolver(dictonary);
                    mavenConfiguration = new MavenConfigurationImpl(resolver, ServiceConstants.PID);
                }
            }
        } catch (IOException e) {
            logger.error("Error retrieving maven configuration",e);
        }
        return mavenConfiguration;
    }

    /**
     * Returns the bundles that match
     * @param url
     * @return
     */
    public List<Bundle> getBundlesByURL(String url) {
        List<Bundle> bundleList = new ArrayList<Bundle>();
        try {
            Long id = Long.parseLong(url);
            Bundle bundle = bundleContext.getBundle(id);
            if (bundle != null) {
                bundleList.add(bundle);
            }
        } catch (NumberFormatException e) {
            for (int i = 0; i < bundleContext.getBundles().length; i++) {
                Bundle bundle = bundleContext.getBundles()[i];
                if (isMavenSnapshotUrl(bundle.getLocation()) && wildCardMatch(bundle.getLocation(), url)) {
                    bundleList.add(bundle);
                }
            }
        }
        return bundleList;
    }

    protected boolean isMavenSnapshotUrl(String url) {
        return url.startsWith("mvn:") && url.contains("SNAPSHOT");
    }

    /**
     * Matches text using a pattern containing wildcards.
     *
     * @param text
     * @param pattern
     * @return
     */
    protected boolean wildCardMatch(String text, String pattern) {
        String[] cards = pattern.split("\\*");
        // Iterate over the cards.
        for (String card : cards) {
            int idx = text.indexOf(card);
            // Card not detected in the text.
            if (idx == -1) {
                return false;
            }

            // Move ahead, towards the right of the text.
            text = text.substring(idx + card.length());
        }
        return true;
    }


    public void start() {
        // register the bundle listener
        bundleContext.addBundleListener(this);
        // start the watch thread
        if (running.compareAndSet(false, true)) {
            if (watchURLs.size()>0) {
                Thread thread = new Thread(this);
                thread.start();
            }
        }
    }

    /**
     * Stops the execution of the thread and releases the singleton instance
     */
    public void stop() {
        running.set(false);
        // unregister the bundle listener
        bundleContext.removeBundleListener(this);
    }

    public ConfigurationAdmin getConfigurationAdmin() {
        return configurationAdmin;
    }

    public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
        this.configurationAdmin = configurationAdmin;
    }

    public BundleContext getBundleContext() {
        return bundleContext;
    }

    public void setBundleContext(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }

    public List<String> getWatchURLs() {
        return watchURLs;
    }

    public void setWatchURLs(List<String> watchURLs) {
        this.watchURLs = watchURLs;
    }

    public long getInterval() {
        return interval;
    }

    public void setInterval(long interval) {
        this.interval = interval;
    }

    public boolean isRunning() {
        return running.get();
    }

}
