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

import org.apache.openejb.loader.IO;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * The goal of this class is to combine several git repositories and branches into
 * one canonical base that can be used with jbake.
 *
 * Repositories are cloned outside of target into a '/repos/' directory so that
 * repeated running can be supported.  Subsequent runs will do a git pull to check
 * for new content.
 *
 * The prepare step will copy relevant asciidoc and markdown sources into the
 * target/jbake/content/<name> directory.
 *
 */
public class Sources {

    /**
     * The directory where all final html files are placed
     * after generation.
     */
    private final File generated;


    /**
     * The directory where all JBake input is aggregated
     * to create one big source tree prior to generation.
     */
    private final File jbake;

    /**
     * The directory where we are keeping a cache of git
     * clones of the repos and branches that contribute
     * to the content of the site.
     */
    private final File repos;

    /**
     * The directory where we are keeping a cache of git
     * clones of the repos and branches that contribute
     * to the content of the site.
     */
    private final File mainSource;


    /**
     * The definition of each repo/branch that contributes
     * to the content of the site.
     */
    private final List<Source> sources = new ArrayList<>();

    public Sources(final File jbake, final File repos, final File mainSource, final File generated, final Source... sources) {
        this(jbake, repos, mainSource, generated, Arrays.asList(sources));
    }

    public Sources(final File jbake, final File repos, final File mainSource, final File generated, final List<Source> sources) {
        this.generated = generated;
        this.jbake = jbake;
        this.repos = repos;
        this.mainSource = mainSource;

        jbake.mkdirs();
        repos.mkdirs();

        this.sources.addAll(sources);
        for (final Source source : sources) {
            if (source.isLatest()) {
                this.sources.add(new Source(source.getScmUrl(), source.getBranch(), "latest"));
                break;
            }
        }
    }

    public File getGenerated() {
        return generated;
    }

    public File getRepos() {
        return repos;
    }

    public File getMainSource() {
        return mainSource;
    }

    public File getJbake() {
        return jbake;
    }

    public List<Source> getSources() {
        return sources;
    }

    /**
     * This is the heart of the code to merge several documentation
     * sources into one tree.
     */
    public void prepare() {
        final Docs docs = new Docs(this);
        final Javadocs javadocs = new Javadocs(this);
        final Examples examples = new Examples(this);
        final VersionIndex versionIndex = new VersionIndex(this);
        final LearningLinks learningLinks = new LearningLinks(examples);
        final Jakartize jakartize = new Jakartize();

        try {
            IO.copyDirectory(mainSource, jbake);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // Download the git repo associated with each Source
        // including any related Source/git repos
        sources.stream()
                .flatMap(Source::stream)
                .peek(source -> source.setDir(new File(repos, source.getName())))
                .forEach(Repos::download);

        // Run any initial steps to process each
        // source root (excluding the related repos)
        sources.stream()
                .peek(jakartize::prepare)
                .peek(docs::prepare)
                .peek(javadocs::prepare)
                .peek(examples::prepare)
                .peek(versionIndex::prepare)
                .peek(learningLinks::prepare)
                .forEach(Sources::prepared);

        // Run any final tasks that have been registered
        // with any Source instance during the prepare phase
        sources.stream()
                .flatMap(Source::stream)
                .map(Source::getPerform)
                .flatMap(Collection::stream)
                .forEach(Runnable::run);

        VersionsIndex.prepare(this);
    }

    /**
     * This is the heart of the code to merge several documentation
     * sources into one tree.
     */
    public void post() {
        final Javadocs javadocs = new Javadocs(this);

        sources.stream()
                .peek(javadocs::prepare)
                .forEach(Sources::prepared);
        ;
    }

    public File getJbakeContentDestFor(final Source source, final String... parts) {
        final File content = new File(jbake, "content");
        File dir = new File(content, source.getName());

        for (final String part : parts) {
            dir = new File(dir, part);
        }

        if (!dir.exists()) {
            if (!dir.mkdirs()) throw new RuntimeException("Could not make directory: " + dir.getAbsolutePath());
        }
        return dir;
    }

    public File getGeneratedDestFor(final Source source, final String... parts) {
        File dir = new File(generated, source.getName());

        for (final String part : parts) {
            dir = new File(dir, part);
        }

        if (!dir.exists()) {
            if (!dir.mkdirs()) throw new RuntimeException("Could not make directory: " + dir.getAbsolutePath());
        }
        return dir;
    }

    private static void prepared(final Source source) {
        System.out.println("Prepared " + source);
    }

}
