///usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 14+
//DEPS guru.nidi:graphviz-java:0.18.1
/*
 * 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 guru.nidi.graphviz.attribute.*;
import guru.nidi.graphviz.engine.Engine;
import guru.nidi.graphviz.engine.Format;
import guru.nidi.graphviz.engine.Graphviz;
import guru.nidi.graphviz.model.*;
import guru.nidi.graphviz.parse.Parser;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Pattern;

import static guru.nidi.graphviz.model.Factory.*;

public class ReactorGraph {
    private static final LinkedHashMap<String, Pattern> CLUSTER_PATTERNS = new LinkedHashMap<>();
    static {
        CLUSTER_PATTERNS.put("JLine", Pattern.compile("^org\\.jline:.*"));
        CLUSTER_PATTERNS.put("Maven API", Pattern.compile("^org\\.apache\\.maven:maven-api-(?!impl).*"));
        CLUSTER_PATTERNS.put("Maven Resolver", Pattern.compile("^org\\.apache\\.maven\\.resolver:.*"));
        CLUSTER_PATTERNS.put("Maven Implementation", Pattern.compile("^org\\.apache\\.maven:maven-(support|impl|di|core|cli|xml|jline|logging|executor):.*"));
        CLUSTER_PATTERNS.put("Maven Compatibility", Pattern.compile("^org\\.apache\\.maven:maven-(artifact|builder-support|compat|embedder|model|model-builder|plugin-api|repository-metadata|resolver-provider|settings|settings-builder|toolchain-builder|toolchain-model):.*"));
        CLUSTER_PATTERNS.put("Sisu", Pattern.compile("(^org\\.eclipse\\.sisu:.*)|(.*:guice:.*)|(.*:javax.inject:.*)|(.*:javax.annotation-api:.*)"));
        CLUSTER_PATTERNS.put("Plexus", Pattern.compile("^org\\.codehaus\\.plexus:.*"));
        CLUSTER_PATTERNS.put("XML Parsing", Pattern.compile("(.*:woodstox-core:.*)|(.*:stax2-api:.*)"));
        CLUSTER_PATTERNS.put("Wagon", Pattern.compile("^org\\.apache\\.maven\\.wagon:.*"));
        CLUSTER_PATTERNS.put("SLF4j", Pattern.compile("^org\\.slf4j:.*"));
        CLUSTER_PATTERNS.put("Commons", Pattern.compile("^commons-cli:.*"));
    }
    private static final Pattern HIDDEN_NODES = Pattern.compile(".*:(maven-docgen|roaster-api|roaster-jdt|velocity-engine-core|commons-lang3|asm|logback-classic|slf4j-simple):.*");

    public static void main(String[] args) {
        try {
            // Parse DOT file
            MutableGraph originalGraph = new Parser().read(new File("target/graph/reactor-graph.dot"));

            // Create final graph
            MutableGraph clusteredGraph = mutGraph("G").setDirected(true);
            clusteredGraph.graphAttrs().add(GraphAttr.COMPOUND);
            clusteredGraph.graphAttrs().add(Label.of("Reactor Graph"));

            // Create clusters
            Map<String, MutableGraph> clusters = new HashMap<>();
            for (String clusterName : CLUSTER_PATTERNS.keySet()) {
                String key = "cluster_" + clusterName.replaceAll("\\s+", "");
                MutableGraph cluster = mutGraph(key).setDirected(true);
                cluster.graphAttrs().add(Label.of(clusterName));
                clusters.put(clusterName, cluster);
                clusteredGraph.add(cluster);
            }

            // Map to store new nodes by node name
            Map<String, MutableNode> nodeMap = new HashMap<>();
            Map<String, String> nodeToCluster = new HashMap<>();
            Map<String, String> newNames = new HashMap<>();

            // First pass: Create nodes and organize them into clusters
            for (MutableNode originalNode : originalGraph.nodes()) {
                String oldNodeName = originalNode.name().toString();
                if (HIDDEN_NODES.matcher(oldNodeName).matches()) {
                    continue;
                }
                String nodeName = oldNodeName;
                if (originalNode.get("label") instanceof Label l) {
                    nodeName = l.value();
                }
                MutableNode newNode = mutNode(nodeName);
                nodeMap.put(nodeName, newNode);
                newNames.put(oldNodeName, nodeName);

                boolean added = false;
                for (Map.Entry<String, Pattern> entry : CLUSTER_PATTERNS.entrySet()) {
                    if (entry.getValue().matcher(oldNodeName).matches()) {
                        clusters.get(entry.getKey()).add(newNode);
                        nodeToCluster.put(nodeName, entry.getKey());
                        added = true;
                        break;
                    }
                }

                if (!added) {
                    clusteredGraph.add(newNode);
                }
            }

            // Second pass: Add links to the clustered graph
            Map<String, MutableNode> substitutes = new HashMap<>();
            Set<Pair> existingLinks = new HashSet<>();
            for (MutableNode node : originalGraph.nodes()) {
                for (Link link : node.links()) {
                    String sourceName = newNames.get(link.from().name().toString());
                    String targetName = newNames.get(link.to().name().toString());
                    String sourceCluster = nodeToCluster.get(sourceName);
                    String targetCluster = nodeToCluster.get(targetName);
                    MutableNode sourceNode = nodeMap.get(sourceName);
                    MutableNode targetNode = nodeMap.get(targetName);
                    if (sourceNode != null && targetNode != null ) {
                        if (!Objects.equals(sourceCluster, targetCluster)) {
                            // Inter-cluster link
                            if (sourceCluster != null) {
                                sourceName = "cluster_" + sourceCluster.replaceAll("\\s+", "");
                            }
                            if (targetCluster != null) {
                                targetName = "cluster_" + targetCluster.replaceAll("\\s+", "");
                            }
                            sourceNode = substitutes.computeIfAbsent(sourceName, n -> createNode(n, clusteredGraph));
                            targetNode = substitutes.computeIfAbsent(targetName, n -> createNode(n, clusteredGraph));
                        }
                        if (existingLinks.add(new Pair(sourceName, targetName))) {
                            sourceNode.addLink(targetNode);
                        }
                    }
                }
            }

            // Write intermediary graph to DOT file
            String dotContent = Graphviz.fromGraph(clusteredGraph).render(Format.DOT).toString();
            Files.write(Paths.get("target/graph/intermediary_graph.dot"), dotContent.getBytes());
            System.out.println("Intermediary graph written to intermediary_graph.dot");

            // Render graph to SVF
            Graphviz.fromGraph(clusteredGraph)
                    .engine(Engine.FDP)
                    .render(Format.SVG).toFile(new File("target/graph/intermediary_graph.svg"));
            System.out.println("Final graph rendered to intermediary_graph.svg");

            // Generate and render the high-level graph
            MutableGraph highLevelGraph = generateHighLevelGraph(clusteredGraph, clusters, nodeToCluster, nodeMap);

            // Write high-level graph to DOT file
            String highLevelDotContent = Graphviz.fromGraph(highLevelGraph).render(Format.DOT).toString();
            Files.write(Paths.get("target/graph/high_level_graph.dot"), highLevelDotContent.getBytes());
            System.out.println("High-level graph written to high_level_graph.dot");

            // Render high-level graph to SVG
            Graphviz.fromGraph(highLevelGraph)
                    .engine(Engine.DOT)
                    .render(Format.SVG).toFile(new File("target/site/images/maven-deps.svg"));
            System.out.println("High-level graph rendered to high_level_graph.svg");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static MutableGraph generateHighLevelGraph(MutableGraph clusteredGraph, Map<String, MutableGraph> clusters,
                                                       Map<String, String> nodeToCluster, Map<String, MutableNode> nodeMap) {
        MutableGraph highLevelGraph = mutGraph("HighLevelGraph").setDirected(true);
        highLevelGraph.graphAttrs().add(GraphAttr.COMPOUND);
        highLevelGraph.graphAttrs().add(Label.of("High-Level Reactor Graph"));

        Map<String, MutableNode> highLevelNodes = new HashMap<>();

        // Create nodes for each cluster
        for (Map.Entry<String, MutableGraph> entry : clusters.entrySet()) {
            String key = entry.getKey();
            String clusterName = key.replaceAll("\\s+", "");
            MutableGraph cluster = entry.getValue();

            String headerColor = clusterName.startsWith("Maven") ? "black" : "#808080";  // #808080 is a middle gray
            StringBuilder labelBuilder = new StringBuilder();
            labelBuilder.append("<table border='0' cellborder='0' cellspacing='0'>");
            labelBuilder.append("<tr><td bgcolor='")
                    .append(headerColor)
                    .append("'><font color='white'>")
                    .append(key)
                    .append("</font></td></tr>");
            cluster.nodes().stream().map(MutableNode::name).map(Label::toString).sorted()
                    .forEach(nodeName -> {
                        labelBuilder.append("<tr>");
                        String prefix = null;
                        switch (clusterName) {
                            case "MavenAPI": prefix = "../api/"; break;
                            case "MavenImplementation": prefix = "../maven-impl-modules/"; break;
                            case "MavenCompatibility": prefix = "../maven-compat-modules/"; break;
                            case "MavenResolver": prefix = "https://maven.apache.org/resolver/"; break;
                        }
                        if (prefix != null) {
                            labelBuilder.append("<td")
                                    .append(" href=\"")
                                    .append(prefix)
                                    .append(nodeName)
                                    .append("\"")
                                    .append(" title=\"")
                                    .append(nodeName)
                                    .append("\"")
                                    .append(" target=\"_parent\"")
                                    .append(">")
                                    .append(nodeName)
                                    .append("</td>");
                        } else {
                            labelBuilder.append("<td>").append(nodeName).append("</td>");
                        }
                        labelBuilder.append("</tr>");
                    });
            labelBuilder.append("</table>");

            MutableNode clusterNode = mutNode(clusterName).add(Label.html(labelBuilder.toString()))
                    .add("shape", "rectangle");
            highLevelNodes.put(clusterName, clusterNode);
            highLevelGraph.add(clusterNode);
        }

        // Add individual nodes for unclustered nodes
        for (MutableNode node : clusteredGraph.nodes()) {
            String nodeName = node.name().toString();
            if (!nodeToCluster.containsKey(nodeName) && !nodeName.startsWith("cluster_")) {
                throw new IllegalStateException("All nodes should be in a cluster: " + node.name());
            }
        }

        // Add edges
        Set<Pair> existingLinks = new HashSet<>();
        for (MutableNode node : clusteredGraph.nodes()) {
            String sourceName = node.name().toString().replace("cluster_", "");
            String sourceCluster = nodeToCluster.getOrDefault(sourceName, sourceName);

            for (Link link : node.links()) {
                String targetName = link.to().name().toString().replace("cluster_", "");
                String targetCluster = nodeToCluster.getOrDefault(targetName, targetName);

                Pair linkPair = new Pair(sourceCluster, targetCluster);
                if (existingLinks.add(linkPair)) {
                    MutableNode sourceNode = highLevelNodes.get(sourceCluster);
                    MutableNode targetNode = highLevelNodes.get(targetCluster);
                    if (sourceNode != null && targetNode != null && sourceNode != targetNode) {
                        sourceNode.addLink(targetNode);
                    }
                }
            }
        }

        return highLevelGraph;
    }

    private static MutableNode createNode(String n, MutableGraph clusteredGraph) {
        MutableNode t = mutNode(n);
        clusteredGraph.add(t);
        return t;
    }

    record Pair(String from, String to) {};
}