/*
 * 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.
 */

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Stream;
import org.apache.maven.search.api.Record;
import org.apache.maven.search.api.SearchRequest;
import org.apache.maven.search.backend.smo.SmoSearchBackend;
import org.apache.maven.search.backend.smo.SmoSearchBackendFactory;
import org.apache.maven.artifact.versioning.ComparableVersion;

import static org.apache.maven.search.api.MAVEN.ARTIFACT_ID;
import static org.apache.maven.search.api.MAVEN.CLASSIFIER;
import static org.apache.maven.search.api.MAVEN.GROUP_ID;
import static org.apache.maven.search.api.MAVEN.VERSION;
import static org.apache.maven.search.api.request.BooleanQuery.and;
import static org.apache.maven.search.api.request.FieldQuery.fieldQuery;

/**
 * Scans for binaries-list files and checks if newer versions of the declared dependencies exist.
 * 
 * dependencies:
 * <pre>org.apache.maven.indexer:search-backend-smo</pre>
 * <pre>org.apache.maven:maven-artifact</pre>
 * 
 * @author mbien
 */
public class BinariesListUpdates {

    private static final LongAdder updates = new LongAdder();
    private static final LongAdder checks = new LongAdder();
    private static final LongAdder skips = new LongAdder();

    // java --class-path "lib/*" BinariesListUpdates.java /path/to/netbeans/project
    public static void main(String[] args) throws IOException, InterruptedException {

        if (args.length != 1 || Files.notExists(Path.of(args[0]).resolve("README.md"))) {
            throw new IllegalArgumentException("path to netbeans folder expected");
        }

        Path path = Path.of(args[0]);
        try (Stream<Path> dependencyFiles = Files.find(path, 10, (p, a) -> p.getFileName().toString().equals("binaries-list"));
             SmoSearchBackend backend = SmoSearchBackendFactory.createSmo()) {
            dependencyFiles.sorted().forEach(p -> {
                try {
                    checkDependencies(p, backend);
                } catch (IOException | InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
            });
        }

        System.out.println("checked " + checks.sum() + " dependencies, found " + updates.sum() + " updates, skipped " + skips.sum() + "." );
    }

    private static void checkDependencies(Path path, SmoSearchBackend backend) throws IOException, InterruptedException {
        System.out.println(path);
        try (Stream<String> lines = Files.lines(path).parallel()) {

            // 321C614F85F1DEA6BB08C1817C60D53B7F3552FD org.fusesource.jansi:jansi:2.4.0
            lines.filter(l -> !l.startsWith("#"))
                 .filter(l -> l.length() > 40 && l.charAt(40) == ' ')
                 .map(l -> l.substring(40+1))
                 .forEach(l -> {

                String[] comp = l.split("\\:");
                if (comp.length == 3 || comp.length == 4) {
                    String gid = comp[0].strip();
                    String aid = comp[1].strip();
                    String version = comp[2].strip();
                    String classifier = comp.length == 4 ? comp[3].strip() : null;
                    try {
                        String gac;
                        String latest;
                        if (classifier == null) {
                            latest = queryLatestVersion(backend, gid, aid);
                            gac = String.join(":", gid, aid);
                        } else {
                            latest = queryLatestVersion(backend, gid, aid, classifier.split("@")[0]);
                            gac = String.join(":", gid, aid, classifier);
                        }
                        if (latest != null && !version.equals(latest)) {
                            System.out.printf("    %-50s %s -> %s\n", gac, version, latest);
                            updates.increment();
                        }
                    } catch (IOException | InterruptedException ex) {
                        throw new RuntimeException(ex);
                    }
                } else {
                    System.out.println("    skip: '"+l+"'");
                    skips.increment();
                }
                checks.increment();
            });
        }
        System.out.println();
    }

    private static String queryLatestVersion(SmoSearchBackend backend, String gid, String aid) throws IOException, InterruptedException {
        return queryLatestVersion(backend, new SearchRequest(and(fieldQuery(GROUP_ID, gid), fieldQuery(ARTIFACT_ID, aid))));
    }

    private static String queryLatestVersion(SmoSearchBackend backend, String gid, String aid, String classifier) throws IOException, InterruptedException {
        return queryLatestVersion(backend, new SearchRequest(and(fieldQuery(GROUP_ID, gid), fieldQuery(ARTIFACT_ID, aid), fieldQuery(CLASSIFIER, classifier))));
    }

    // reduce concurrency level if needed
    private final static Semaphore requests = new Semaphore(3);

    private static String queryLatestVersion(SmoSearchBackend backend, SearchRequest request) throws IOException, InterruptedException {
        requests.acquire();
        try {
            List<Record> results;
            try {
                results = backend.search(request).getPage();
            } catch (IOException ex) {
                System.out.println("received exception: '" + ex.getMessage() + "', retry in 10s");
                Thread.sleep(10_000);
                try {
                    results = backend.search(request).getPage();
                } catch(IOException ignore) {
                    throw ex;
                }
            }
            return results.stream()
                    .map(r -> r.getValue(VERSION))
                    .filter(v -> !v.contains("alpha") && !v.contains("beta"))
                    .filter(v -> !v.contains("M") && !v.contains("m") && !v.contains("B") && !v.contains("b") && !v.contains("ea") && !v.contains("RC"))
                    .limit(5)
                    .max((v1, v2) -> new ComparableVersion(v1).compareTo(new ComparableVersion(v2)))
                    .orElse(null);
        } finally {
            requests.release();
        }
    }

}
