/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed 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.onlab.jdvue;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Set;

/**
 * Generator of a self-contained HTML file which serves as a GUI for
 * visualizing Java package dependencies carried in the supplied catalog.
 *
 * The HTML file is an adaptation of D3.js Hierarchical Edge Bundling as
 * shown at http://bl.ocks.org/mbostock/7607999.
 *
 * @author Thomas Vachuska
 */
public class DependencyViewer {

    private static final String JPD_EXT = ".db";
    private static final String HTML_EXT = ".html";

    private static final String INDEX = "index.html";
    private static final String D3JS = "d3.v3.min.js";

    private static final String TITLE_PLACEHOLDER = "TITLE_PLACEHOLDER";
    private static final String D3JS_PLACEHOLDER = "D3JS_PLACEHOLDER";
    private static final String DATA_PLACEHOLDER = "DATA_PLACEHOLDER";

    private final Catalog catalog;

    /**
     * Creates a Java package dependency viewer.
     *
     * @param catalog dependency catalog
     */
    public DependencyViewer(Catalog catalog) {
        this.catalog = catalog;
    }

    /**
     * Main program entry point.
     *
     * @param args command line arguments
     */
    public static void main(String[] args) {
        Catalog cat = new Catalog();
        DependencyViewer viewer = new DependencyViewer(cat);
        try {
            String path = args[0];
            cat.load(path + JPD_EXT);
            cat.analyze();

            System.err.println(cat);
            viewer.dumpLongestCycle(cat);
            viewer.writeHTMLFile(path);
        } catch (IOException e) {
            System.err.println("Unable to process catalog: " + e.getMessage());
        }
    }

    /**
     * Prints out the longest cycle; just for kicks.
     * @param cat catalog
     */
    private void dumpLongestCycle(Catalog cat) {
        DependencyCycle longest = null;
        for (DependencyCycle cycle : cat.getCycles()) {
            if (longest == null || longest.getCycleSegments().size() < cycle.getCycleSegments().size()) {
                longest = cycle;
            }
        }

        if (longest != null) {
            for (Dependency dependency : longest.getCycleSegments()) {
                System.out.println(dependency);
            }
        }
    }

    /**
     * Writes the HTML catalog file for the given viewer.
     *
     * @param path base file path
     * @throws IOException if issues encountered writing the HTML file
     */
    public void writeHTMLFile(String path) throws IOException {
        String index = slurp(getClass().getResourceAsStream(INDEX));
        String d3js = slurp(getClass().getResourceAsStream(D3JS));

        FileWriter fw = new FileWriter(path + HTML_EXT);
        ObjectWriter writer = new ObjectMapper().writer(); // .writerWithDefaultPrettyPrinter();
        fw.write(index.replace(TITLE_PLACEHOLDER, path)
                         .replace(D3JS_PLACEHOLDER, d3js)
                         .replace(DATA_PLACEHOLDER, writer.writeValueAsString(toJson())));
        fw.close();
    }

    /**
     * Slurps the specified input stream into a string.
     *
     * @param stream input stream to be read
     * @return string containing the contents of the input stream
     * @throws IOException if issues encountered reading from the stream
     */
     static String slurp(InputStream stream) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(stream));
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append(System.lineSeparator());
        }
        br.close();
        return sb.toString();
    }

    // Produces a JSON structure designed to drive the hierarchical visual
    // representation of Java package dependencies and any dependency cycles
     private JsonNode toJson() {
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode root = mapper.createObjectNode();
        root.put("packages", jsonPackages(mapper));
        root.put("cycleSegments", jsonCycleSegments(mapper, catalog.getCycleSegments()));
        root.put("summary", jsonSummary(mapper));
        return root;
    }

    // Produces a JSON summary of dependencies
    private JsonNode jsonSummary(ObjectMapper mapper) {
        ObjectNode summary = mapper.createObjectNode();
        summary.put("packages", catalog.getPackages().size());
        summary.put("sources", catalog.getSources().size());
        summary.put("cycles", catalog.getCycles().size());
        summary.put("cycleSegments", catalog.getCycleSegments().size());
        return summary;
    }

    // Produces a JSON structure with package dependency data
    private JsonNode jsonPackages(ObjectMapper mapper) {
        ArrayNode packages = mapper.createArrayNode();
        for (JavaPackage javaPackage : catalog.getPackages()) {
            packages.add(json(mapper, javaPackage));
        }
        return packages;
    }

    // Produces a JSON structure with all cyclic segments
    private JsonNode jsonCycleSegments(ObjectMapper mapper,
                                       Set<Dependency> segments) {
        ObjectNode cyclicSegments = mapper.createObjectNode();
        for (Dependency dependency : segments) {
            String s = dependency.getSource().name();
            String t = dependency.getTarget().name();
            cyclicSegments.put(t + "-" + s,
                               mapper.createObjectNode().put("s", s).put("t", t));
        }
        return cyclicSegments;
    }

    // Produces a JSON object structure describing the specified Java package.
    private JsonNode json(ObjectMapper mapper, JavaPackage javaPackage) {
        ObjectNode node = mapper.createObjectNode();

        ArrayNode imports = mapper.createArrayNode();
        for (JavaPackage dependency : javaPackage.getDependencies()) {
            imports.add(dependency.name());
        }

        Set<DependencyCycle> packageCycles = catalog.getPackageCycles(javaPackage);
        Set<Dependency> packageCycleSegments = catalog.getPackageCycleSegments(javaPackage);

        node.put("name", javaPackage.name());
        node.put("size", javaPackage.getSources().size());
        node.put("imports", imports);
        node.put("cycleSegments", jsonCycleSegments(mapper, packageCycleSegments));
        node.put("cycleCount", packageCycles.size());
        node.put("cycleSegmentCount", packageCycleSegments.size());
        return node;
    }

}
