/*
 * 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.meecrowave.doc;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.MapConfiguration;
import org.apache.meecrowave.Meecrowave;
import org.apache.meecrowave.doc.generator.ArquillianConfiguration;
import org.apache.meecrowave.doc.generator.CliConfiguration;
import org.apache.meecrowave.doc.generator.Configuration;
import org.apache.meecrowave.doc.generator.Downloads;
import org.apache.meecrowave.doc.generator.GradleConfiguration;
import org.apache.meecrowave.doc.generator.LetsEncryptConfiguration;
import org.apache.meecrowave.doc.generator.MavenConfiguration;
import org.apache.meecrowave.doc.generator.OAuth2Configuration;
import org.apache.meecrowave.doc.generator.ProxyConfiguration;
import org.jbake.app.Oven;
import org.jbake.app.configuration.ConfigUtil;
import org.jbake.app.configuration.DefaultJBakeConfiguration;

import com.orientechnologies.orient.core.Orient;

public class JBake {
    private JBake() {
        // no-op
    }

    // if you want to switch off PDF generation use as arguments: src/main/jbake target/site-tmp true false
    public static void main(final String[] args) throws Exception {
        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "64"); // try to have parallelStream better than default

        final File source = args == null || args.length < 1 ? new File("src/main/jbake") : new File(args[0]);
        final File pdfSource = new File(source, "content");
        final File destination = args == null || args.length < 2 ? new File("target/site-tmp") : new File(args[1]);
        final boolean startHttp = args == null || args.length < 2 || Boolean.parseBoolean(args[2]); // by default we dev
        final boolean skipPdf = args != null && args.length > 3 && !Boolean.parseBoolean(args[3]); // by default...too slow sorry
        final boolean updateDownloads = args != null && args.length > 4 && Boolean.parseBoolean(args[4]); // grabs central

        // generation of dynamic content
        new Configuration().run();
        new CliConfiguration().run();
        new ArquillianConfiguration().run();
        new MavenConfiguration().run();
        new OAuth2Configuration().run();
        new LetsEncryptConfiguration().run();
        new GradleConfiguration().run();
        new ProxyConfiguration().run();

        if (updateDownloads) {
            final ByteArrayOutputStream tableContent = new ByteArrayOutputStream();
            try (final PrintStream stream = new PrintStream(tableContent)) {
                Downloads.doMain(stream);
            }
            try (final Writer writer = new FileWriter(new File(source, "content/download.adoc"))) {
                writer.write("= Downloads\n"
                        + ":jbake-generated: true\n"
                        + ":jbake-date: 2017-07-24\n"
                        + ":jbake-type: page\n"
                        + ":jbake-status: published\n"
                        + ":jbake-meecrowavepdf:\n"
                        + ":jbake-meecrowavecolor: body-blue\n"
                        + ":icons: font\n"
                        + "\n"
                        + "License under Apache License v2 (ALv2).\n"
                        + "\n"
                        + "[.table.table-bordered,options=\"header\"]\n"
                        + "|===\n"
                        + "|Name|Version|Date|Size|Type|Links\n");
                writer.write(new String(tableContent.toByteArray(), StandardCharsets.UTF_8));
                writer.write("\n|===\n");
            }
        }

        final Runnable build = () -> {
            System.out.println("Building Meecrowave website in " + destination);
            final Orient orient = Orient.instance();
            try {
                orient.startup();

                final Oven oven = new Oven(source, destination, new CompositeConfiguration() {{
                    final CompositeConfiguration config = new CompositeConfiguration();
                    config.addConfiguration(new MapConfiguration(new HashMap<String, Object>() {{
                        put("asciidoctor.attributes", new ArrayList<String>() {{
                            add("source-highlighter=highlightjs");
                            add("highlightjs-theme=idea");
                            add("context_rootpath=/meecrowave");
                        }});
                    }}));
                    config.addConfiguration(DefaultJBakeConfiguration.class.cast(
                            new ConfigUtil().loadConfig(source)).getCompositeConfiguration());
                    addConfiguration(config);
                }}, true);
                oven.setupPaths();

                System.out.println("  > baking");
                oven.bake();

                if (!skipPdf) {
                    System.out.println("  > pdfifying");
                    PDFify.generatePdf(pdfSource, destination);
                }

                System.out.println("  > done :)");
            } catch (final Exception e) {
                e.printStackTrace();
            } finally {
                orient.shutdown();
            }
        };

        build.run();
        if (startHttp) {
            final Path watched = source.toPath();
            final WatchService watchService = watched.getFileSystem().newWatchService();
            watched.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
            final AtomicBoolean run = new AtomicBoolean(true);
            final AtomicLong render = new AtomicLong(-1);
            final Thread renderingThread = new Thread() {
                {
                    setName("jbake-renderer");
                }

                @Override
                public void run() {
                    long last = System.currentTimeMillis();
                    while (run.get()) {
                        if (render.get() > last) {
                            last = System.currentTimeMillis();
                            try {
                                build.run();
                            } catch (final Throwable oops) {
                                oops.printStackTrace();
                            }
                        }
                        try {
                            sleep(TimeUnit.SECONDS.toMillis(1));
                        } catch (final InterruptedException e) {
                            Thread.interrupted();
                            break;
                        }
                    }
                    System.out.println("Exiting renderer");
                }
            };
            final Thread watcherThread = new Thread() {
                {
                    setName("jbake-file-watcher");
                }

                @Override
                public void run() {
                    while (run.get()) {
                        try {
                            final WatchKey key = watchService.poll(1, TimeUnit.SECONDS);
                            if (key == null) {
                                continue;
                            }

                            for (final WatchEvent<?> event : key.pollEvents()) {
                                final WatchEvent.Kind<?> kind = event.kind();
                                if (kind != ENTRY_CREATE && kind != ENTRY_DELETE && kind != ENTRY_MODIFY) {
                                    continue; // unlikely but better to protect ourself
                                }

                                final Path updatedPath = Path.class.cast(event.context());
                                if (kind == ENTRY_DELETE || updatedPath.toFile().isFile()) {
                                    final String path = updatedPath.toString();
                                    if (!path.contains("___jb") && !path.endsWith("~")) {
                                        render.set(System.currentTimeMillis());
                                    }
                                }
                            }
                            key.reset();
                        } catch (final InterruptedException e) {
                            Thread.interrupted();
                            run.compareAndSet(true, false);
                        } catch (final ClosedWatchServiceException cwse) {
                            if (!run.get()) {
                                throw new IllegalStateException(cwse);
                            }
                        }
                    }
                    System.out.println("Exiting file watcher");
                }
            };

            renderingThread.start();
            watcherThread.start();

            final Runnable onQuit = () -> {
                run.compareAndSet(true, false);
                Stream.of(watcherThread, renderingThread).forEach(thread -> {
                    try {
                        thread.join();
                    } catch (final InterruptedException e) {
                        Thread.interrupted();
                    }
                });
                try {
                    watchService.close();
                } catch (final IOException ioe) {
                    // not important
                }
            };

            try (final Meecrowave container = new Meecrowave(new Meecrowave.Builder() {{
                setWebResourceCached(false);
            }}) {{
                start();
                deployWebapp("/meecrowave", destination);
            }}) {
                System.out.println("Started on http://localhost:" + container.getConfiguration().getHttpPort() + "/meecrowave");

                final Scanner console = new Scanner(System.in);
                String cmd;
                while (((cmd = console.nextLine())) != null) {
                    if ("quit".equals(cmd)) {
                        break;
                    } else if ("r".equals(cmd) || "rebuild".equals(cmd) || "build".equals(cmd) || "b".equals(cmd)) {
                        render.set(System.currentTimeMillis());
                    } else {
                        System.err.println("Ignoring " + cmd + ", please use 'build' or 'quit'");
                    }
                }
            }
            onQuit.run();
        }
    }
}
