/**
 * Copyright (C) 2008 Google Inc.
 *
 * 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 com.google.inject.grapher.graphviz;

import com.google.common.base.Join;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.grapher.ImplementationNode;
import com.google.inject.grapher.NodeAliasFactory;
import com.google.inject.grapher.Renderer;

import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * {@link Renderer} implementation that writes out a Graphviz DOT file of the
 * graph. Bound in {@link GraphvizModule}.
 * <p>
 * Specify the {@link PrintWriter} to output to with
 * {@link #setOut(PrintWriter)}.
 *
 * @author phopkins@gmail.com (Pete Hopkins)
 */
public class GraphvizRenderer implements Renderer, NodeAliasFactory<String> {
  private final List<GraphvizNode> nodes = Lists.newArrayList();
  private final List<GraphvizEdge> edges = Lists.newArrayList();
  private final Map<String, String> aliases = Maps.newHashMap();
  
  private PrintWriter out;
  private String rankdir = "TB";

  public GraphvizRenderer setOut(PrintWriter out) {
    this.out = out;
    return this;
  }

  public GraphvizRenderer setRankdir(String rankdir) {
    this.rankdir = rankdir;
    return this;
  }

  public void addNode(GraphvizNode node) {
    nodes.add(node);
  }
  
  public void addEdge(GraphvizEdge edge) {
    edges.add(edge);
  }

  public void newAlias(String fromId, String toId) {
    aliases.put(fromId, toId);
  }

  protected String resolveAlias(String id) {
    while (aliases.containsKey(id)) {
      id = aliases.get(id);
    }
    
    return id;
  }
  
  public void render() {
    start();
    
    for (GraphvizNode node : nodes) {
      renderNode(node);
    }

    for (GraphvizEdge edge : edges) {
      renderEdge(edge);
    }
    
    finish();
    
    out.flush();
  }

  protected Map<String, String> getGraphAttributes() {
    Map<String, String> attrs = Maps.newHashMap();
    attrs.put("rankdir", rankdir);
    return attrs;
  }

  protected void start() {
    out.println("digraph injector {");
    
    Map<String, String> attrs = getGraphAttributes();
    out.println("graph " + getAttrString(attrs) + ";");
  }

  protected void finish() {
    out.println("}");
  }

  protected void renderNode(GraphvizNode node) {
    Map<String, String> attrs = getNodeAttributes(node);
    out.println(node.getNodeId() + " " + getAttrString(attrs));       
  }
  
  protected Map<String, String> getNodeAttributes(GraphvizNode node) {
    Map<String, String> attrs = Maps.newHashMap();

    attrs.put("label", getNodeLabel(node));
    // remove most of the margin because the table has internal padding
    attrs.put("margin", "0.02,0");
    attrs.put("shape", node.getShape().toString());
    attrs.put("style", node.getStyle().toString());
    
    return attrs;
  }

  /**
   * Creates the "label" for a node. This is a string of HTML that defines a
   * table with a heading at the top and (in the case of
   * {@link ImplementationNode}s) rows for each of the member fields.
   */
  protected String getNodeLabel(GraphvizNode node) {
    String cellborder = node.getStyle() == NodeStyle.INVISIBLE ? "1" : "0";
    
    StringBuilder html = new StringBuilder();
    html.append("<");
    html.append("<table cellspacing=\"0\" cellpadding=\"5\" cellborder=\"");
    html.append(cellborder).append("\" border=\"0\">");
    
    html.append("<tr>").append("<td align=\"left\" port=\"header\" ");
    html.append("bgcolor=\"" + node.getHeaderBackgroundColor() + "\">");
    
    String subtitle = Join.join("<br align=\"left\"/>", node.getSubtitles());
    if (subtitle.length() != 0) {
      html.append("<font color=\"").append(node.getHeaderTextColor());
      html.append("\" point-size=\"10\">");
      html.append(subtitle).append("<br align=\"left\"/>").append("</font>");
    }

    html.append("<font color=\"" + node.getHeaderTextColor() + "\">");
    html.append(htmlEscape(node.getTitle())).append("<br align=\"left\"/>");
    html.append("</font>").append("</td>").append("</tr>");

    for (Map.Entry<String, String> field : node.getFields().entrySet()) {
      html.append("<tr>");
      html.append("<td align=\"left\" port=\"").append(field.getKey()).append("\">");
      html.append(htmlEscape(field.getValue()));
      html.append("</td>").append("</tr>");
    }

    html.append("</table>");
    html.append(">");
    return html.toString();
  }

  protected void renderEdge(GraphvizEdge edge) {
    Map<String, String> attrs = getEdgeAttributes(edge);
    
    String tailId = getEdgeEndPoint(resolveAlias(edge.getTailNodeId()), edge.getTailPortId(),
        edge.getTailCompassPoint());

    String headId = getEdgeEndPoint(resolveAlias(edge.getHeadNodeId()), edge.getHeadPortId(),
        edge.getHeadCompassPoint());
    
    out.println(tailId + " -> " + headId + " " + getAttrString(attrs));
  }

  protected Map<String, String> getEdgeAttributes(GraphvizEdge edge) {
    Map<String, String> attrs = Maps.newHashMap();
    
    attrs.put("arrowhead", getArrowString(edge.getArrowHead()));
    attrs.put("arrowtail", getArrowString(edge.getArrowTail()));
    attrs.put("style", edge.getStyle().toString());
    
    return attrs;
  }
  
  private String getAttrString(Map<String, String> attrs) {
    List<String> attrList = Lists.newArrayList();
    
    for (Entry<String, String> attr : attrs.entrySet()) {
      String value = attr.getValue();

      if (value != null) {
        attrList.add(attr.getKey() + "=" + value);
      }
    }
    
    return "[" + Join.join(", ", attrList) + "]";
  }

  /**
   * Turns a {@link List} of {@link ArrowType}s into a {@link String} that
   * represents combining them. With Graphviz, that just means concatenating
   * them.
   */
  protected String getArrowString(List<ArrowType> arrows) {
    return Join.join("", arrows);
  }

  protected String getEdgeEndPoint(String nodeId, String portId, CompassPoint compassPoint) {
    List<String> portStrings = Lists.newArrayList(nodeId);
    
    if (portId != null) {
      portStrings.add(portId);
    }
    
    if (compassPoint != null) {
      portStrings.add(compassPoint.toString());
    }
    
    return Join.join(":", portStrings);
  }

  protected String htmlEscape(String str) {
    return str.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
  }
}
