//! Simple graphviz dot file format output.

use std::fmt::{self, Display, Write};
use {
    Graph,
    EdgeType,
    GraphMap,
};
use super::graph::IndexType;
use graphmap::NodeTrait;
use std::collections::HashMap;

/// `Dot` implements output to graphviz .dot format for a graph.
///
/// Formatting and options are rather simple, this is mostly intended
/// for debugging. Exact output may change.
pub struct Dot<'a, G: 'a> {
    graph: &'a G,
    config: &'a [Config],
}

static TYPE: [&'static str; 2] = ["graph", "digraph"];
static EDGE: [&'static str; 2] = ["--", "->"];
static INDENT: &'static str = "    ";

impl<'a, G> Dot<'a, G> {
    /// Create a `Dot` formatting wrapper with default configuration.
    pub fn new(graph: &'a G) -> Self {
        Self::with_config(graph, &[])
    }

    /// Create a `Dot` formatting wrapper with custom configuration.
    pub fn with_config(graph: &'a G, config: &'a [Config]) -> Self {
        Dot {
            graph: graph,
            config: config,
        }
    }
}

/// `Dot` configuration.
///
/// This enum does not have an exhaustive definition (will be expanded)
#[derive(Debug, PartialEq, Eq)]
pub enum Config {
    /// Use indices for node labels.
    NodeIndexLabel,
    /// Use indices for edge labels.
    EdgeIndexLabel,
    /// Use no edge labels.
    EdgeNoLabel,
    #[doc(hidden)]
    _Incomplete(()),
}

impl<'a, N, E, Ty, Ix> Dot<'a, Graph<N, E, Ty, Ix>>
    where Ty: EdgeType,
          Ix: IndexType,
{
    fn graph_fmt<F, G>(&self, f: &mut fmt::Formatter,
                       mut node_fmt: F, mut edge_fmt: G) -> fmt::Result
        where F: FnMut(&N, &mut FnMut(&Display) -> fmt::Result) -> fmt::Result,
              G: FnMut(&E, &mut FnMut(&Display) -> fmt::Result) -> fmt::Result,
{
        let g = self.graph;
        try!(writeln!(f, "{} {{", TYPE[g.is_directed() as usize]));

        // output all labels
        for index in g.node_indices() {
            try!(write!(f, "{}{}", INDENT, index.index()));
            if self.config.contains(&Config::NodeIndexLabel) {
                try!(writeln!(f, ""));
            } else {
                try!(write!(f, " [label=\""));
                try!(node_fmt(&g[index], &mut |d| Escaped(d).fmt(f)));
                try!(writeln!(f, "\"]"));
            }

        }
        // output all edges
        for (i, edge) in g.raw_edges().iter().enumerate() {
            try!(write!(f, "{}{} {} {}",
                        INDENT,
                        edge.source().index(),
                        EDGE[g.is_directed() as usize],
                        edge.target().index()));
            if self.config.contains(&Config::EdgeNoLabel) {
                try!(writeln!(f, ""));
            } else if self.config.contains(&Config::EdgeIndexLabel) {
                try!(writeln!(f, " [label=\"{}\"]", i));
            } else {
                try!(write!(f, " [label=\""));
                try!(edge_fmt(&edge.weight, &mut |d| Escaped(d).fmt(f)));
                try!(writeln!(f, "\"]"));
            }
        }

        try!(writeln!(f, "}}"));
        Ok(())
    }
}

impl<'a, N, E, Ty, Ix> fmt::Display for Dot<'a, Graph<N, E, Ty, Ix>>
    where N: fmt::Display,
          E: fmt::Display,
          Ty: EdgeType,
          Ix: IndexType,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graph_fmt(f, |n, cb| cb(n), |e, cb| cb(e))
    }
}

impl<'a, N, E, Ty, Ix> fmt::Debug for Dot<'a, Graph<N, E, Ty, Ix>>
    where N: fmt::Debug,
          E: fmt::Debug,
          Ty: EdgeType,
          Ix: IndexType,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graph_fmt(f,
                       |n, cb| cb(&DebugFmt(n)),
                       |e, cb| cb(&DebugFmt(e)))
    }
}

impl<'a, N, E> Dot<'a, GraphMap<N, E>>
    where N: NodeTrait,
{
    fn graphmap_fmt<F, G>(&self, f: &mut fmt::Formatter,
                          mut node_fmt: F, mut edge_fmt: G) -> fmt::Result
        where F: FnMut(&N, &mut FnMut(&Display) -> fmt::Result) -> fmt::Result,
              G: FnMut(&E, &mut FnMut(&Display) -> fmt::Result) -> fmt::Result,
    {
        let g = self.graph;
        try!(writeln!(f, "{} {{", TYPE[0]));

        let mut labels = HashMap::new();

        // output all labels
        for (i, node) in g.nodes().enumerate() {
            labels.insert(node, i);
            try!(write!(f, "{}{}", INDENT, i));
            if self.config.contains(&Config::NodeIndexLabel) {
                try!(writeln!(f, ""));
            } else {
                try!(write!(f, " [label=\""));
                try!(node_fmt(&node, &mut |d| Escaped(d).fmt(f)));
                try!(writeln!(f, "\"]"));
            }
        }
        // output all edges
        for (i, (a, b, edge_weight)) in g.all_edges().enumerate() {
            try!(write!(f, "{}{} {} {}",
                        INDENT,
                        labels[&a],
                        EDGE[0],
                        labels[&b]));
            if self.config.contains(&Config::EdgeNoLabel) {
                try!(writeln!(f, ""));
            } else if self.config.contains(&Config::EdgeIndexLabel) {
                try!(writeln!(f, " [label=\"{}\"]", i));
            } else {
                try!(write!(f, " [label=\""));
                try!(edge_fmt(&edge_weight, &mut |d| Escaped(d).fmt(f)));
                try!(writeln!(f, "\"]"));
            }
        }

        try!(writeln!(f, "}}"));
        Ok(())
    }
}
impl<'a, N, E> fmt::Display for Dot<'a, GraphMap<N, E>>
    where N: fmt::Display + NodeTrait,
          E: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graphmap_fmt(f, |n, cb| cb(n), |e, cb| cb(e))
    }
}

impl<'a, N, E> fmt::Debug for Dot<'a, GraphMap<N, E>>
    where N: fmt::Debug + NodeTrait,
          E: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.graphmap_fmt(f,
                          |n, cb| cb(&DebugFmt(n)),
                          |e, cb| cb(&DebugFmt(e)))
    }
}

/// Escape for Graphviz
struct Escaper<W>(W);

impl<W> fmt::Write for Escaper<W>
    where W: fmt::Write
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for c in s.chars() {
            try!(self.write_char(c));
        }
        Ok(())
    }

    fn write_char(&mut self, c: char) -> fmt::Result {
        match c {
            '"' => try!(self.0.write_char('\\')),
            // \l is for left justified linebreak
            '\n' => return self.0.write_str(r#"\l"#),
            _   => { }
        }
        self.0.write_char(c)
    }
}

/// Pass Display formatting through a simple escaping filter
struct Escaped<T>(T);

impl<T> fmt::Display for Escaped<T>
    where T: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if f.alternate() {
            write!(&mut Escaper(f), "{:#}\\l", &self.0)
        } else {
            write!(&mut Escaper(f), "{}", &self.0)
        }
    }
}

/// Pass Debug formatting to Display
struct DebugFmt<T>(T);

impl<T> fmt::Display for DebugFmt<T>
    where T: fmt::Debug
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}
