/*
    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.installer.provider.installhook;

import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.apache.commons.lang.StringUtils;
import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
import org.apache.jackrabbit.vault.fs.io.Archive;
import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
import org.apache.jackrabbit.vault.fs.io.ImportOptions;
import org.apache.jackrabbit.vault.packaging.InstallContext;
import org.apache.jackrabbit.vault.packaging.InstallHook;
import org.apache.jackrabbit.vault.packaging.PackageException;
import org.apache.jackrabbit.vault.packaging.PackageProperties;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
import org.apache.sling.installer.api.InstallableResource;
import org.apache.sling.installer.api.OsgiInstaller;
import org.apache.sling.installer.api.event.InstallationEvent;
import org.apache.sling.installer.api.event.InstallationListener;
import org.apache.sling.installer.api.info.InfoProvider;
import org.apache.sling.installer.api.info.InstallationState;
import org.apache.sling.installer.api.info.Resource;
import org.apache.sling.installer.api.info.ResourceGroup;
import org.apache.sling.installer.api.tasks.ResourceState;
import org.apache.sling.installer.api.tasks.TaskResource;
import org.apache.sling.settings.SlingSettingsService;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OsgiInstallerHook implements InstallHook {

    private static final Logger LOG = LoggerFactory.getLogger(OsgiInstallerHook.class);

    private static final String PACKAGE_PROP_INSTALL_PATH_REGEX = "installPathRegex";
    private static final String PACKAGE_PROPERTY_MAX_WAIT_IN_SEC = "maxWaitForOsgiInstallerInSec";
    private static final String PACKAGE_PROPERTY_INSTALL_PRIORITY = "osgiInstallerPriority";
    private static final String PACKAGE_PROPERTY_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC = "waitForOsgiEventsQuietInSec";

    public static final int DEFAULT_PRIORITY_INSTALL_HOOK = 2000;
    private static final int DEFAULT_MAX_WAIT_IN_SEC = 60;
    private static final int DEFAULT_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC = 1;

    public static final String URL_SCHEME = "jcrinstall";
    public static final String CONFIG_SUFFIX = ".config";
    public static final String JAR_SUFFIX = ".jar";

    private static final String ENTITY_ID_PREFIX_BUNDLE = "bundle:";

    private static final String MANIFEST_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
    private static final String MANIFEST_BUNDLE_VERSION = "Bundle-Version";
    private static final String FOLDER_META_INF = "META-INF";

    static final String JCR_CONTENT = "jcr:content";
    static final String JCR_CONTENT_DATA = JCR_CONTENT + "/jcr:data";
    static final String JCR_LAST_MODIFIED = "jcr:lastModified";
    static final String JCR_CONTENT_LAST_MODIFIED = JCR_CONTENT + "/" + JCR_LAST_MODIFIED;

    public static final String DOT = ".";

    InstallHookLogger logger = new InstallHookLogger();

    public OsgiInstallerHook() {
        LOG.debug("Preloading classes to ensure to not run into a NoClassDefFoundError"
                + " due to a reloading dynamic classloader: {}, {}, {}, {}",
                new Object[] { TaskResource.class, InstallationEvent.TYPE.class, ResourceState.class,
                        InstallerHookOsgiEventListener.class });
    }

    @Override
    public void execute(InstallContext context) throws PackageException {

        VaultPackage vaultPackage = context.getPackage();
        PackageProperties packageProperties = vaultPackage.getProperties();
        String installPathRegex = packageProperties.getProperty(PACKAGE_PROP_INSTALL_PATH_REGEX);

        ServiceReference<OsgiInstaller> osgiInstallerServiceRef = null;
        ServiceReference<SlingSettingsService> slingSettingsServiceRef = null;
        ServiceRegistration<InstallationListener> hookInstallationListenerServiceRegistration = null;

        ServiceReference<InfoProvider> infoProviderServiceRef = null;

        try {
            switch (context.getPhase()) {
            case PREPARE:
                if (StringUtils.isBlank(installPathRegex)) {
                    throw new IllegalArgumentException(
                            "When using OSGi installer install hook for synchronous installation, the package property "
                                    + PACKAGE_PROP_INSTALL_PATH_REGEX + " has to be provided.");
                }
                break;
            case INSTALLED:
                ImportOptions options = context.getOptions();
                logger.setOptions(options);

                logger.log(getClass().getSimpleName() + " is active in " + vaultPackage.getId());

                List<BundleInPackage> bundleResources = new ArrayList<>();
                List<String> configResourcePaths = new ArrayList<>();
                Archive archive = vaultPackage.getArchive();

                infoProviderServiceRef = getBundleContext().getServiceReference(InfoProvider.class);
                InfoProvider infoProvider = (InfoProvider) getBundleContext().getService(infoProviderServiceRef);
                InstallationState installationState = infoProvider.getInstallationState();

                slingSettingsServiceRef = getBundleContext().getServiceReference(SlingSettingsService.class);
                SlingSettingsService slingSettingsService = (SlingSettingsService) getBundleContext().getService(slingSettingsServiceRef);
                Set<String> runModes = slingSettingsService.getRunModes();

                collectResources(archive, archive.getRoot(), "", bundleResources, configResourcePaths, installPathRegex,
                        runModes);

                logger.log("Bundles in package " + bundleResources);

                Session session = context.getSession();

                Map<String, InstallableResource> bundlesToInstallByUrl = getBundlesToInstall(bundleResources, session, installationState,
                        packageProperties);
                Map<String, InstallableResource> configsToInstallByUrl = getConfigsToInstall(configResourcePaths, session,
                        installationState, packageProperties);

                if (bundlesToInstallByUrl.isEmpty() && configsToInstallByUrl.isEmpty()) {
                    logger.log("No installable resources that are not installed yet found.");
                    return;
                }

                logger.log("Installing " + bundlesToInstallByUrl.size() + " bundles and "
                        + configsToInstallByUrl.size() + " configs");
                osgiInstallerServiceRef = getBundleContext().getServiceReference(OsgiInstaller.class);
                OsgiInstaller osgiInstaller = getBundleContext().getService(osgiInstallerServiceRef);

                OsgiInstallerListener hookInstallationListener = new OsgiInstallerListener(bundlesToInstallByUrl.keySet(),
                        configsToInstallByUrl.keySet());
                hookInstallationListenerServiceRegistration = getBundleContext()
                        .registerService(InstallationListener.class, hookInstallationListener, null);

                List<InstallableResource> resourcesToUpdate = new ArrayList<>();
                resourcesToUpdate.addAll(bundlesToInstallByUrl.values());
                resourcesToUpdate.addAll(configsToInstallByUrl.values());
                logger.log("Updating resources " + resourcesToUpdate);
                osgiInstaller.updateResources(URL_SCHEME, resourcesToUpdate.toArray(new InstallableResource[resourcesToUpdate.size()]),
                        null);

                int maxWaitForOsgiInstallerInSec = getNumericPackageProperty(packageProperties, PACKAGE_PROPERTY_MAX_WAIT_IN_SEC,
                        DEFAULT_MAX_WAIT_IN_SEC);

                long startTime = System.currentTimeMillis();
                int bundlesLeftToInstall = 0;
                int configsLeftToInstall = 0;
                while ((bundlesLeftToInstall = hookInstallationListener.bundlesLeftToInstall()) > 0
                        || (configsLeftToInstall = hookInstallationListener.configsLeftToInstall()) > 0) {
                    if ((System.currentTimeMillis() - startTime) > maxWaitForOsgiInstallerInSec * 1000) {
                        logger.log("Installable resources " + resourcesToUpdate
                                + " could not be installed even after waiting " + maxWaitForOsgiInstallerInSec + "sec");
                        break;
                    }
                    logger.log("Waiting for " + bundlesLeftToInstall + " bundles / " + configsLeftToInstall + " configs to be installed");
                    Thread.sleep(1000);

                    // the events are not always reliably received, also update listener explicitly with current installation state
                    hookInstallationListener.updateWith(infoProvider.getInstallationState().getInstalledResources());
                }
                if (bundlesLeftToInstall == 0 && configsLeftToInstall == 0) {
                    logger.log("All " + bundlesToInstallByUrl.size() + " bundles / " + configsToInstallByUrl.size()
                            + " configs have been successfully installed in " + (System.currentTimeMillis() - startTime) + "ms");
                }

                int waitForOsgiEventsQuietInSec = getNumericPackageProperty(packageProperties,
                        PACKAGE_PROPERTY_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC, DEFAULT_WAIT_FOR_OSGI_EVENTS_QUIET_IN_SEC);
                waitForServiceChanges(waitForOsgiEventsQuietInSec);

                break;
            default:
                break;
            }
        } catch (Exception e) {
            throw new PackageException("Could not execute install hook to for synchronous installation: " + e, e);
        } finally {
            if (osgiInstallerServiceRef != null) {
                getBundleContext().ungetService(osgiInstallerServiceRef);
            }
            if (slingSettingsServiceRef != null) {
                getBundleContext().ungetService(slingSettingsServiceRef);
            }
            if (infoProviderServiceRef != null) {
                getBundleContext().ungetService(infoProviderServiceRef);
            }

            if (hookInstallationListenerServiceRegistration != null) {
                hookInstallationListenerServiceRegistration.unregister();
            }
        }
    }

    private int getNumericPackageProperty(PackageProperties packageProperties, String propertyName, int defaultVal) {
        String strVal = packageProperties.getProperty(propertyName);
        int intVal = strVal != null ? Integer.parseInt(strVal) : defaultVal;
        return intVal;
    }

    private Map<String, InstallableResource> getBundlesToInstall(List<BundleInPackage> bundlesInPackage, Session session,
            InstallationState installationState, PackageProperties packageProperties) throws RepositoryException, IOException {
        Map<String, InstallableResource> installableResources = new HashMap<>();
        Iterator<BundleInPackage> bundlesIt = bundlesInPackage.iterator();
        while (bundlesIt.hasNext()) {
            BundleInPackage bundle = bundlesIt.next();

            List<Resource> currentInstallerBundleResources = getBundleResources(installationState, bundle.symbolicName);

            boolean needsInstallation = false;
            if (currentInstallerBundleResources.isEmpty()) {
                needsInstallation = true;
            } else if (currentInstallerBundleResources.size() == 1) {
                Resource resource = currentInstallerBundleResources.get(0);

                if (resource.getState() == ResourceState.INSTALLED) {
                    String currentlyActiveBundleVersion = resource.getVersion().toString();
                    if (!StringUtils.equals(currentlyActiveBundleVersion, bundle.version)) {
                        logger.log("Bundle " + bundle.symbolicName + " is installed with version "
                                + currentlyActiveBundleVersion + " but package contains version " + bundle.version);
                        needsInstallation = true;
                    } else {
                        logger.log("Bundle " + bundle.symbolicName + " is already installed with version "
                                + currentlyActiveBundleVersion + " that matches " + bundle.version + " as provided in package");
                    }
                } else {
                    String msg = MessageFormat.format("Bundle {0} is not in state INSTALLED but in {1}", bundle.symbolicName, resource.getState());
                    if (StringUtils.isNotEmpty(resource.getError())) {
                        // related error if there is some
                        msg += " due to error '" + resource.getError() + "'";
                    }
                    logger.log(msg);
                    needsInstallation = true;
                }

            } else {
                logger.log("Bundle " + bundle.symbolicName + " exists with multiple installer resources");
                boolean installedBundleResourceFound = false;
                for (Resource resource : currentInstallerBundleResources) {
                    logger.log("Resource " + resource);
                    if (resource.getState() == ResourceState.INSTALLED
                            && StringUtils.equals(resource.getVersion().toString(), bundle.version)) {
                        installedBundleResourceFound = true;
                    }
                }
                if (!installedBundleResourceFound) {
                    needsInstallation = true;
                }

            }

            if (needsInstallation) {
                logger.log("Bundle " + bundle.symbolicName + " requires installation");
                Node node = session.getNode(bundle.path);
                InstallableResource installableResource = convert(node, bundle.path, packageProperties);
                String bundleUrl = URL_SCHEME + ":" + bundle.path;
                installableResources.put(bundleUrl, installableResource);
            }
        }
        return installableResources;
    }

    private List<Resource> getBundleResources(InstallationState installationState, String symbolicId) {

        List<Resource> bundleResources = new ArrayList<Resource>();

        List<ResourceGroup> allGroups = new ArrayList<ResourceGroup>();
        allGroups.addAll(installationState.getInstalledResources());
        allGroups.addAll(installationState.getActiveResources());
        for (ResourceGroup resourceGroup : allGroups) {
            List<Resource> resources = resourceGroup.getResources();
            for (Resource resource : resources) {
                if (StringUtils.equals(resource.getEntityId(), ENTITY_ID_PREFIX_BUNDLE + symbolicId)) {
                    bundleResources.add(resource);
                }
            }
        }
        return bundleResources;
    }

    private Map<String, InstallableResource> getConfigsToInstall(List<String> configResourcePaths, Session session,
            InstallationState installationState, PackageProperties packageProperties)
            throws IOException, InvalidSyntaxException, RepositoryException {
        Map<String, InstallableResource> configsToInstallByUrl = new HashMap<>();
        for (String configResourcePath : configResourcePaths) {
            boolean needsInstallation = false;

            String configUrl = URL_SCHEME + ":" + configResourcePath;
            boolean configFound = false;
            List<ResourceGroup> installedResources = installationState.getInstalledResources();
            for (ResourceGroup resourceGroup : installedResources) {
                for (Resource resource : resourceGroup.getResources()) {
                    if (StringUtils.equals(configUrl, resource.getURL())) {
                        configFound = true;
                        logger.log("Config " + configResourcePath + " is already installed");
                    }
                }
            }
            if (!configFound) {
                logger.log("Config " + configResourcePath + " has not been installed");
                needsInstallation = true;
            }

            if (needsInstallation) {

                Node node = session.getNode(configResourcePath);
                InstallableResource installableResource = convert(node, configResourcePath, packageProperties);

                configsToInstallByUrl.put(configUrl, installableResource);
            }
        }
        return configsToInstallByUrl;
    }

    void collectResources(Archive archive, Entry entry, String dirPath, List<BundleInPackage> bundleResources,
            List<String> configResources, String installPathRegex, Set<String> actualRunmodes) {
        String entryName = entry.getName();
        if (entryName.equals(FOLDER_META_INF)) {
            return;
        }

        String dirPathWithoutJcrRoot = StringUtils.substringAfter(dirPath, "/jcr_root");
        String entryPath = dirPathWithoutJcrRoot + entryName;
        String dirPathWithoutSlash = StringUtils.chomp(dirPathWithoutJcrRoot, "/");

        boolean runmodesMatch;
        if (dirPathWithoutSlash.contains(DOT)) {
            String[] bits = dirPathWithoutSlash.split("\\" + DOT, 2);
            List<String> runmodesOfResource = Arrays.asList(bits[1].split("\\" + DOT));
            Set<String> matchingRunmodes = new HashSet<String>(runmodesOfResource);
            matchingRunmodes.retainAll(actualRunmodes);
            LOG.debug("Entry with runmode(s): entryPath={} runmodesOfResource={} actualRunmodes={} matchingRunmodes={}",
                    entryPath, runmodesOfResource, actualRunmodes, matchingRunmodes);
            runmodesMatch = matchingRunmodes.size() == runmodesOfResource.size();
            if (!runmodesMatch) {
                logger.log("Skipping installation of  " + entryPath
                        + " because the path is not matching all actual runmodes " + actualRunmodes);
            }
        } else {
            runmodesMatch = true;
        }

        if (entryPath.matches(installPathRegex) && runmodesMatch) {

            if (entryName.endsWith(CONFIG_SUFFIX)) {
                configResources.add(entryPath);
            } else if (entryName.endsWith(JAR_SUFFIX)) {
                try (InputStream entryInputStream = archive.getInputSource(entry).getByteStream();
                        JarInputStream jarInputStream = new JarInputStream(entryInputStream)) {
                    Manifest manifest = jarInputStream.getManifest();
                    String symbolicName = manifest.getMainAttributes().getValue(MANIFEST_BUNDLE_SYMBOLIC_NAME);
                    String version = manifest.getMainAttributes().getValue(MANIFEST_BUNDLE_VERSION);

                    bundleResources.add(new BundleInPackage(entryPath, symbolicName, version));
                } catch (Exception e) {
                    throw new IllegalStateException(
                            "Could not read symbolic name and version from manifest of bundle " + entryName);
                }
            }

        }

        for (Entry child : entry.getChildren()) {
            collectResources(archive, child, dirPath + entryName + "/", bundleResources, configResources,
                    installPathRegex, actualRunmodes);
        }
    }

    InstallableResource convert(final Node node, final String path, PackageProperties packageProperties)
            throws IOException, RepositoryException {
        LOG.trace("Converting {} at path {}", node, path);
        final String digest = String.valueOf(node.getProperty(JCR_CONTENT_LAST_MODIFIED).getDate().getTimeInMillis());
        final InputStream is = node.getProperty(JCR_CONTENT_DATA).getBinary().getStream();
        final Dictionary<String, Object> dict = new Hashtable<String, Object>();
        dict.put(InstallableResource.INSTALLATION_HINT, node.getParent().getName());
        int priority = getNumericPackageProperty(packageProperties, PACKAGE_PROPERTY_INSTALL_PRIORITY, DEFAULT_PRIORITY_INSTALL_HOOK);
        return new InstallableResource(path, is, dict, digest, null, priority);
    }

    private void waitForServiceChanges(int waitForOsgiEventsQuietInSec) {
        if (waitForOsgiEventsQuietInSec <= 0) {
            return;
        }
        InstallerHookOsgiEventListener osgiListener = new InstallerHookOsgiEventListener();
        BundleContext bundleContext = getBundleContext();
        bundleContext.addServiceListener(osgiListener);
        bundleContext.addBundleListener(osgiListener);

        long waitStart = System.currentTimeMillis();
        osgiListener.waitUntilQuiet(waitForOsgiEventsQuietInSec);
        logger.log("Waited " + (System.currentTimeMillis() - waitStart) + "ms in total for OSGi events to become quiet (for at least "
                + waitForOsgiEventsQuietInSec + "sec)");

        bundleContext.removeServiceListener(osgiListener);
        bundleContext.removeBundleListener(osgiListener);

    }

    // always get fresh bundle context to avoid "Dynamic class loader has already
    // been deactivated" exceptions
    private BundleContext getBundleContext() {
        // use the vault bundle to hook into the OSGi world
        Bundle currentBundle = FrameworkUtil.getBundle(InstallHook.class);
        if (currentBundle == null) {
            throw new IllegalStateException(
                    "The class " + InstallHook.class + " was not loaded through a bundle classloader");
        }
        BundleContext bundleContext = currentBundle.getBundleContext();
        if (bundleContext == null) {
            throw new IllegalStateException("Could not get bundle context for bundle " + currentBundle);
        }
        return bundleContext;
    }

    class BundleInPackage {
        final String path;
        final String symbolicName;
        final String version;

        public BundleInPackage(String path, String symbolicName, String version) {
            super();
            this.path = path;
            this.symbolicName = symbolicName;
            this.version = version;
        }

        @Override
        public String toString() {
            return "BundleInPackage [path=" + path + ", symbolicId=" + symbolicName + ", version=" + version + "]";
        }

    }

    static class InstallHookLogger {

        private ProgressTrackerListener listener;

        public void setOptions(ImportOptions options) {
            this.listener = options.getListener();
        }

        public void logError(Logger logger, String message, Throwable throwable) {
            if (listener != null) {
                listener.onMessage(ProgressTrackerListener.Mode.TEXT, "ERROR: " + message, "");
            }
            logger.error(message, throwable);
        }

        public void log(String message) {
            log(LOG, message);
        }

        public void log(Logger logger, String message) {
            if (listener != null) {
                listener.onMessage(ProgressTrackerListener.Mode.TEXT, message, "");
            }
            logger.info(message);
        }
    }

    static class InstallerHookOsgiEventListener implements ServiceListener, BundleListener {

        private long lastEventTimestamp = System.currentTimeMillis();

        @Override
        public void serviceChanged(ServiceEvent event) {
            lastEventTimestamp = System.currentTimeMillis();
            LOG.trace("Service changed event {}", event);
        }

        @Override
        public void bundleChanged(BundleEvent event) {
            lastEventTimestamp = System.currentTimeMillis();
            LOG.trace("Bundle changed event {}", event);
        }

        public void waitUntilQuiet(long waitInSec) {
            try {
                while (System.currentTimeMillis() - lastEventTimestamp < waitInSec * 1000) {
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                LOG.warn("Wait for OSGi events was interrupted");
            }
        }
    }

}
