/*
 * 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.geronimo.microprofile.site;

import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME;
import static java.util.Arrays.asList;
import static java.util.Optional.ofNullable;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.text.WordUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

// regenerate when needed only, useless to do it for any site update
public class Downloads {

    private static final SAXParserFactory FACTORY = SAXParserFactory.newInstance();

    // always available once the release passed compared to central
    private static final String ASF_BASE = "https://repository.apache.org/content/repositories/releases/";

    // the entry point we want on the download page
    private static final String MVN_BASE = "http://repo.maven.apache.org/maven2/";

    private static final long KILO_RATION = 1024;

    static {
        FACTORY.setNamespaceAware(false);
        FACTORY.setValidating(false);
    }

    private Downloads() {
        // no-op
    }

    public static void main(final String[] args) {
        Locale.setDefault(Locale.ENGLISH);

        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "512");

        final List<Download> downloads = Stream.of("org/apache/geronimo/config/geronimo-config-impl", "org/apache/geronimo/safeguard/safeguard-impl",
                "org/apache/geronimo/geronimo-jwt-auth", "org/apache/geronimo/geronimo-opentracing",
                "org/apache/geronimo/geronimo-health", "org/apache/geronimo/geronimo-metrics",
                "org/apache/geronimo/geronimo-openapi-impl", "org/apache/geronimo/geronimo-microprofile-aggregator")
                .flatMap(Downloads::toVersions)
                .map(v -> v.base.endsWith("geronimo-microprofile-aggregator") ? v.extensions("pom") : v.extensions("jar"))
                .flatMap(Downloads::toDownloadable).map(Downloads::fillDownloadable).filter(Objects::nonNull)
                .sorted(Downloads::versionComparator)
                .map(Downloads::toCentral)
                .collect(toList());

        final Collection<Download> lastReleases = downloads.stream()
                .collect(toMap(Download::getName, identity(), (a, b) -> a))
                .values().stream()
                .sorted(Downloads::versionComparator)
                .collect(toList());

        System.out.println("= Downloads\n:jbake-date: 2018-07-24\n:icons: font\n\n");
        System.out.println("== Last releases\n\n");
        System.out.println(tableHeader());
        lastReleases.forEach(Downloads::printRow);
        System.out.println(tableFooter());
        System.out.println();
        System.out.println("== Previous releases\n\n");
        downloads.stream()
                .filter(it -> !lastReleases.contains(it))
                .collect(groupingBy(Download::getName))
                .forEach((name, dls) -> {
                    System.out.println("=== " + name + "\n\n");
                    System.out.println(tableHeader());
                    dls.forEach(Downloads::printRow);
                    System.out.println(tableFooter());
                    System.out.println();
                });
        System.out.println();
    }

    private static String tableFooter() {
        return "|===";
    }

    private static String tableHeader() {
        return "[.table.table-bordered,options=\"header\"]\n|===\n|Name|Version|Date|Size|Type|Links";
    }

    private static int versionComparator(final Download o1, final Download o2) {
        final int formatComp = o2.format.compareTo(o1.format); // pom before jar
        if (formatComp != 0) {
            return formatComp;
        }

        final int nameComp = o1.name.compareTo(o2.name);
        if (nameComp != 0) {
            return nameComp;
        }

        final int versionComp = o2.version.compareTo(o1.version);
        if (versionComp != 0) {
            return versionComp;
        }

        final long dateComp = LocalDateTime.parse(o2.date, RFC_1123_DATE_TIME).toInstant(ZoneOffset.UTC)
                .toEpochMilli()
                - LocalDateTime.parse(o1.date, RFC_1123_DATE_TIME).toInstant(ZoneOffset.UTC).toEpochMilli();
        if (dateComp != 0) {
            return (int) dateComp;
        }

        return o1.url.compareTo(o2.url);
    }

    private static Download toCentral(final Download download) {
        final Download dl = new Download(
                normalizeName(download.name),
                download.classifier,
                download.version,
                download.format,
                download.url.replace(ASF_BASE, MVN_BASE),
                download.sha1.replace(ASF_BASE, MVN_BASE),
                download.asc.replace(ASF_BASE, MVN_BASE));
        dl.date = download.date;
        dl.size = download.size;
        return dl;
    }

    private static String normalizeName(final String name) {
        String out = name;
        if (out.startsWith("Apache ")) {
            out = out.substring("Apache ".length());
        }
        if (!out.startsWith("Geronimo")) {
            out = "Geronimo " + out;
        }
        if (out.endsWith(" Impl")) {
            out = out.substring(0, out.length() - " Impl".length());
        }
        return out;
    }

    private static void printRow(final Download d) {
        System.out.println("|" + d.name + (d.classifier.isEmpty() ? "" : (" " + d.classifier)) + "|"
                + d.version + "|"
                + new SimpleDateFormat("d MMM yyyy")
                        .format(Date.from(LocalDateTime.parse(d.date, RFC_1123_DATE_TIME).toInstant(ZoneOffset.UTC)))
                + "|" + d.size + " kB " + "|" + d.format.toUpperCase() + "| " + d.url + "[icon:download[] "
                + d.format.toUpperCase() + "] " + d.sha1 + "[icon:download[] SHA1] ");
    }

    private static Download fillDownloadable(final Download download) {
        try {
            final URL url = new URL(download.url);
            final HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection());
            connection.setConnectTimeout((int) TimeUnit.SECONDS.toMillis(30));
            final int responseCode = connection.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                if (HttpURLConnection.HTTP_NOT_FOUND != responseCode) {
                    System.err.println("Got " + responseCode + " for " + download.url);
                }
                return null;
            }

            download.setDate(connection.getHeaderField("Last-Modified").replaceAll(" +", " "));
            download.setSize(toMega(ofNullable(connection.getHeaderField("Content-Length")).map(Long::parseLong).orElse(0L),
                    ofNullable(connection.getHeaderField("Accept-Ranges")).orElse("bytes")));

            connection.getInputStream().close();
        } catch (final IOException e) {
            e.printStackTrace();
            return null;
        }
        return download;
    }

    private static long toMega(final long length, final String bytes) {
        if (!"bytes".equalsIgnoreCase(bytes)) {
            throw new IllegalArgumentException("Not handled unit: " + bytes);
        }
        return length / KILO_RATION;
    }

    private static Stream<Download> toDownloadable(final Version version) {
        final String base = version.base;
        final String artifactId = base.substring(base.lastIndexOf('/') + 1);
        final String artifactBase = version.base + "/" + version.version + "/" + artifactId + "-" + version.version;
        return version.extensions.stream()
                .flatMap(e -> (version.classifiers.isEmpty() ? Stream.of(new ArtifactDescription("", e))
                        : version.classifiers.stream().map(c -> new ArtifactDescription(c, e))))
                .map(a -> toDownload(artifactId, a.classifier, version.version, a.extension,
                        artifactBase + (a.classifier.isEmpty() ? '.' + a.extension : ('-' + a.classifier + '.' + a.extension))));
    }

    private static Download toDownload(final String artifactId, final String classifier, final String version,
            final String format, final String url) {
        return new Download(
                WordUtils.capitalize(artifactId.replace('-', ' ')),
                classifier, version, format, url, url + ".sha1", url + ".asc");
    }

    private static Stream<Version> toVersions(final String baseUrl) {
        final QuickMvnMetadataParser handler = new QuickMvnMetadataParser();
        final String base = ASF_BASE + baseUrl;
        try (final InputStream stream = new URL(base + "/maven-metadata.xml").openStream()) {
            final SAXParser parser = FACTORY.newSAXParser();
            parser.parse(stream, handler);
            return handler.foundVersions.stream().map(v -> new Version(base, v)).parallel();
        } catch (final Exception e) {
            if (Boolean.getBoolean("debug")) {
                e.printStackTrace();
            }
            return Stream.empty();
        }
    }

    public static class Version {

        private final String base;

        private final String version;

        private final Collection<String> classifiers = new ArrayList<>();

        private final Collection<String> extensions = new ArrayList<>();

        public Version(final String base, final String version) {
            this.base = base;
            this.version = version;
        }

        private Version extensions(final String... values) {
            extensions.addAll(asList(values));
            return this;
        }

        private Version classifiers(final String... values) {
            classifiers.addAll(asList(values));
            return this;
        }

        public String getBase() {
            return base;
        }

        public String getVersion() {
            return version;
        }

        public Collection<String> getClassifiers() {
            return classifiers;
        }

        public Collection<String> getExtensions() {
            return extensions;
        }
    }

    public static class ArtifactDescription {

        private final String classifier;

        private final String extension;

        public ArtifactDescription(final String classifier, final String extension) {
            this.classifier = classifier;
            this.extension = extension;
        }

        public String getClassifier() {
            return classifier;
        }

        public String getExtension() {
            return extension;
        }
    }

    public static class Download {

        private final String name;

        private final String classifier;

        private final String version;

        private final String format;

        private final String url;

        private final String sha1;

        private final String asc;

        private String date;

        private long size;

        public Download(final String name, final String classifier, final String version, final String format, final String url,
                final String sha1, final String asc) {
            this.name = name;
            this.classifier = classifier;
            this.version = version;
            this.format = format;
            this.url = url;
            this.sha1 = sha1;
            this.asc = asc;
        }

        public String getName() {
            return name;
        }

        public String getClassifier() {
            return classifier;
        }

        public String getVersion() {
            return version;
        }

        public String getFormat() {
            return format;
        }

        public String getUrl() {
            return url;
        }

        public String getSha1() {
            return sha1;
        }

        public String getAsc() {
            return asc;
        }

        public String getDate() {
            return date;
        }

        public void setDate(final String date) {
            this.date = date;
        }

        public long getSize() {
            return size;
        }

        public void setSize(final long size) {
            this.size = size;
        }
    }

    private static class QuickMvnMetadataParser extends DefaultHandler {

        private boolean versioning = false;

        private boolean versions = false;

        private StringBuilder version;

        private final Collection<String> foundVersions = new ArrayList<>();

        @Override
        public void startElement(final String uri, final String localName, final String name, final Attributes attributes)
                throws SAXException {
            if ("versioning".equalsIgnoreCase(name)) {
                versioning = true;
            } else if ("versions".equalsIgnoreCase(name)) {
                versions = true;
            } else if (versioning && versions && "version".equalsIgnoreCase(name)) {
                version = new StringBuilder();
            }
        }

        @Override
        public void characters(final char[] ch, final int start, final int length) {
            if (version != null) {
                version.append(new String(ch, start, length));
            }
        }

        public void endElement(final String uri, final String localName, final String name) {
            if ("versioning".equalsIgnoreCase(name)) {
                versioning = false;
            } else if ("versions".equalsIgnoreCase(name)) {
                versions = false;
            } else if ("version".equalsIgnoreCase(name)) {
                foundVersions.add(version.toString());
            }
        }
    }
}
