/*
 * 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 java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * A Source largely maps to a git repo we will checkout and use to build content
 * to publish to the website.
 *
 * Currently we have the following notable sources:
 *
 *  - tomee-8.0
 *  - tomee-7.1
 *  - tomee-7.0
 *  - microprofile-2.0
 *  - jakartaee-8.0
 *  - master
 *  - latest
 *
 * Each of these sources are given its own section on the website, for example:
 *
 *  - http://tomee.apache.org/jakartaee-8.0/javadoc/
 *  - http://tomee.apache.org/tomee-8.0/javadoc/
 *  - http://tomee.apache.org/tomee-8.0/examples/
 *
 * Sources may include content from other git repos and this act like an aggregator.
 * For example the microprofile-2.0 Source has 8 related Source trees, one for each
 * API in MicroProfile 2.0.  Each git reference includes the right tag information
 * so we are able to get the source (and therefore javadoc) for the exact version in
 * MicroProfile 2.0.
 *
 * We intentionally want the javadoc on our site to keep our links stable and not
 * depending on third-party sites that could change and break our links.  It also
 * allows us to enhance the javadoc to include links to and from our examples.
 * And finally many of these javadocs are not online anywhere, so it allows us to
 * bring some unique value to the world and increase our website traffic.
 */
public class Source {
    private final String name;
    private final String scmUrl;
    private final String branch;
    private final boolean latest;
    private final List<Source> related = new ArrayList<>();
    private File dir;
    private Filter javadocFilter = new Filter(".*/src/main/java/.*", ".*/(tck|itests|examples|archetype-resources|.*-example)/.*");
    private Pattern javadocPackages;

    /**
     * This allows us to attach a handful of finishing actions to
     * each Source that get executed after any 'prepare' methods
     * are called.  This will most likely consist of Lambdas and
     * is effectively a very simple way to split our logic into
     * two phases: prepare, perform.
     */
    private final List<Runnable> perform = new ArrayList<>();

    /**
     * The components map is a simple technique to allow us to attach
     * objects to the Source in various "prepare" phases.  It was initially
     * added to allow {@link Javadocs} to pass data to  {@link LearningLinks}
     * without making the two directly reference on each other.
     *
     * It also allows us to prepare some data that is specific to the Source
     * instance and not see by other Source instances.
     */
    private final Map<Class, Object> components = new HashMap();

    public Source(final String scmUrl, final String branch, final String name) {
        this(scmUrl, branch, name, false);
    }

    public Source(final String scmUrl, final String branch, final String name, final boolean latest) {
        this.scmUrl = scmUrl;
        this.branch = branch;
        this.name = name;
        this.latest = latest;
    }

    public List<Runnable> getPerform() {
        return perform;
    }

    public boolean addPerform(final Runnable runnable) {
        return perform.add(runnable);
    }

    public <T> T setComponent(Class<T> type, T value) {
        return (T) this.components.put(type, value);
    }

    public <T> Optional<T> getComponent(Class<T> type) {
        return Optional.ofNullable((T) this.components.get(type));
    }

    /**
     * Returns stream of this source and all related sources
     */
    public Stream<Source> stream() {
        return Stream.concat(Stream.of(this), this.getRelated().stream());
    }

    public boolean isLatest() {
        return latest;
    }

    public String getScmUrl() {
        return scmUrl;
    }

    public String getBranch() {
        return branch;
    }

    public String getName() {
        return name;
    }

    public File getDir() {
        return dir;
    }

    public void setDir(final File dir) {
        this.dir = dir;
    }

    public List<Source> getRelated() {
        return related;
    }

    public Source related(final Source... related) {
        Collections.addAll(this.related, related);
        return this;
    }

    public Filter getJavadocFilter() {
        return javadocFilter;
    }

    public Source filterJavadoc(final String include, final String exclude) {
        this.javadocFilter = new Filter(include, exclude);
        return this;
    }

    public Pattern getJavadocPackages() {
        return javadocPackages;
    }

    public void setJavadocPackages(final Pattern javadocPackages) {
        this.javadocPackages = javadocPackages;
    }

    public Source javadoc(final String include) {
        this.javadocPackages = Pattern.compile(include);
        return this;
    }


    @Override
    public String toString() {
        return "Source{" +
                "name='" + name + '\'' +
                ", scmUrl='" + scmUrl + '\'' +
                ", branch='" + branch + '\'' +
                '}';
    }

    public static class Filter {
        private final Pattern include;
        private final Pattern exclude;

        public Filter(final String include, final String exclude) {
            this.include = Pattern.compile(include);
            this.exclude = Pattern.compile(exclude);
        }

        public Pattern getInclude() {
            return include;
        }

        public Pattern getExclude() {
            return exclude;
        }

        public boolean include(final File file) {
            return include.matcher(file.getAbsolutePath()).matches();
        }

        public boolean exclude(final File file) {
            return !exclude.matcher(file.getAbsolutePath()).matches();
        }
    }
}
