/**
 * Licensed 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.winegrower;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.apache.winegrower.deployer.OSGiBundleLifecycle;
import org.apache.winegrower.scanner.StandaloneScanner;
import org.apache.winegrower.scanner.manifest.ActivatorManifestContributor;
import org.apache.winegrower.scanner.manifest.BlueprintManifestContributor;
import org.apache.winegrower.scanner.manifest.KarafCommandManifestContributor;
import org.apache.winegrower.scanner.manifest.ManifestContributor;
import org.apache.winegrower.service.BundleRegistry;
import org.apache.winegrower.service.OSGiServices;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public interface Ripener extends AutoCloseable {
    Configuration getConfiguration();

    long getStartTime();

    Ripener start();

    void stop();

    OSGiServices getServices();

    BundleRegistry getRegistry();

    @Override
    void close();

    class Configuration {
        private static final Collection<String> DEFAULT_EXCLUSIONS = asList( // todo: make it configurable
                "slf4j-",
                "xbean-",
                "org.osgi.",
                "opentest4j-"
        );

        private File workDir = new File(System.getProperty("java.io.tmpdir"), "karaf-boot_" + UUID.randomUUID().toString());
        private Predicate<String> jarFilter = it -> DEFAULT_EXCLUSIONS.stream().anyMatch(it::startsWith);
        private Collection<String> scanningIncludes;
        private Collection<String> scanningExcludes;
        private Collection<ManifestContributor> manifestContributors = Stream.concat(
                // built-in
                Stream.of(new KarafCommandManifestContributor(), new ActivatorManifestContributor(), new BlueprintManifestContributor()),
                // extensions
                StreamSupport.stream(ServiceLoader.load(ManifestContributor.class).spliterator(), false)
        ).collect(toList());
        // known bundles
        private List<String> prioritizedBundles = asList(
                "org.apache.aries.blueprint.core",
                "org.apache.aries.blueprint.cm",
                "pax-web-extender-whiteboard",
                "pax-web-runtime");

        public List<String> getPrioritizedBundles() {
            return prioritizedBundles;
        }

        public void setPrioritizedBundles(final List<String> prioritizedBundles) {
            this.prioritizedBundles = prioritizedBundles;
        }

        public Collection<ManifestContributor> getManifestContributors() {
            return manifestContributors;
        }

        public void setManifestContributors(final Collection<ManifestContributor> manifestContributors) {
            this.manifestContributors = manifestContributors;
        }

        public Collection<String> getScanningIncludes() {
            return scanningIncludes;
        }

        public void setScanningIncludes(final Collection<String> scanningIncludes) {
            this.scanningIncludes = scanningIncludes;
        }

        public Collection<String> getScanningExcludes() {
            return scanningExcludes;
        }

        public void setScanningExcludes(final Collection<String> scanningExcludes) {
            this.scanningExcludes = scanningExcludes;
        }

        public File getWorkDir() {
            return workDir;
        }

        public void setWorkDir(final File workDir) {
            this.workDir = workDir;
        }

        public void setJarFilter(final Predicate<String> jarFilter) {
            this.jarFilter = jarFilter;
        }

        public Predicate<String> getJarFilter() {
            return jarFilter;
        }
    }


    class Impl implements Ripener {
        private static final Logger LOGGER = LoggerFactory.getLogger(Ripener.class);

        private final OSGiServices services = new OSGiServices(this);
        private final BundleRegistry registry;

        private final Configuration configuration;

        private long startTime = -1;

        public Impl(final Configuration configuration) {
            this.configuration = configuration;
            this.registry = new BundleRegistry(services, configuration);
        }

        @Override
        public Configuration getConfiguration() {
            return configuration;
        }

        @Override
        public long getStartTime() {
            return startTime;
        }

        @Override
        public synchronized Ripener start() {
            startTime = System.currentTimeMillis();
            LOGGER.info("Starting Apache Winegrower application on {}",
                    LocalDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneId.systemDefault()));
            final StandaloneScanner scanner = new StandaloneScanner(configuration, registry.getFramework());
            final AtomicLong bundleIdGenerator = new AtomicLong(1);
            Stream.concat(scanner.findOSGiBundles().stream(), scanner.findPotentialOSGiBundles().stream())
                    .sorted(this::compareBundles)
                    .map(it -> new OSGiBundleLifecycle(it.getManifest(), it.getJar(), services, registry, configuration, bundleIdGenerator.getAndIncrement()))
                    .peek(OSGiBundleLifecycle::start)
                    .peek(it -> registry.getBundles().put(it.getBundle().getBundleId(), it))
                    .forEach(bundle -> LOGGER.debug("Bundle {}", bundle));
            return this;
        }

        @Override
        public synchronized void stop() {
            LOGGER.info("Stopping Apache Winegrower application on {}", LocalDateTime.now());
            final Map<Long, OSGiBundleLifecycle> bundles = registry.getBundles();
            bundles.values().stream()
                   .sorted((o1, o2) -> (int) (o2.getBundle().getBundleId() - o1.getBundle().getBundleId()))
                   .forEach(OSGiBundleLifecycle::stop);
            bundles.clear();
            if (configuration.getWorkDir().exists()) {
                try {
                    Files.walkFileTree(configuration.getWorkDir().toPath(), new SimpleFileVisitor<Path>() {
                        @Override
                        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
                            Files.delete(file);
                            return super.visitFile(file, attrs);
                        }

                        @Override
                        public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
                            Files.delete(dir);
                            return super.postVisitDirectory(dir, exc);
                        }
                    });
                } catch (final IOException e) {
                    LOGGER.warn("Can't delete work directory", e);
                }
            }
        }

        @Override
        public OSGiServices getServices() {
            return services;
        }

        @Override
        public BundleRegistry getRegistry() {
            return registry;
        }

        @Override // for try with resource syntax
        public void close() {
            stop();
        }

        private int compareBundles(final StandaloneScanner.BundleDefinition bundle1, final StandaloneScanner.BundleDefinition bundle2) {
            final int index1 = matchPriorities(bundle1.getJar().getName());
            final int index2 = matchPriorities(bundle2.getJar().getName());
            if (index1 == index2) {
                return bundle1.getJar().getName().compareTo(bundle2.getJar().getName());
            }
            if (index1 == -1) {
                return 1;
            }
            if (index2 == -1) {
                return -1;
            }
            return index1 - index2;
        }

        private int matchPriorities(final String name) {
            return configuration.getPrioritizedBundles().stream()
                    .filter(name::startsWith)
                    .findFirst()
                    .map(it -> configuration.getPrioritizedBundles().indexOf(it))
                    .orElse(-1);
        }
    }

    static void main(final String[] args) {
        final CountDownLatch latch = new CountDownLatch(1);
        final Ripener main = new Impl(new Configuration()).start();
        Runtime.getRuntime().addShutdownHook(new Thread() {

            {
                setName(getClass().getName() + "-shutdown-hook");
            }

            @Override
            public void run() {
                main.stop();
                latch.countDown();
            }
        });
        try {
            latch.await();
        } catch (final InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}
