//! This module provides linkage between rustc::middle::graph and
//! libgraphviz traits, specialized to attaching borrowck analysis
//! data to rendered labels.

pub use Variant::*;

pub(crate) use crate::cfg::graphviz::{Node, Edge};
use crate::cfg::graphviz as cfg_dot;
use crate::cfg::CFGIndex;
use crate::borrowck::{self, BorrowckCtxt, LoanPath};
use crate::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
use log::debug;
use std::rc::Rc;

#[derive(Debug, Copy, Clone)]
pub enum Variant {
    Loans,
    Moves,
    Assigns,
}

impl Variant {
    pub fn short_name(&self) -> &'static str {
        match *self {
            Loans   => "loans",
            Moves   => "moves",
            Assigns => "assigns",
        }
    }
}

pub struct DataflowLabeller<'a, 'tcx> {
    pub inner: cfg_dot::LabelledCFG<'a, 'tcx>,
    pub variants: Vec<Variant>,
    pub borrowck_ctxt: &'a BorrowckCtxt<'a, 'tcx>,
    pub analysis_data: &'a borrowck::AnalysisData<'tcx>,
}

impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
    fn dataflow_for(&self, e: EntryOrExit, n: &Node<'a>) -> String {
        let id = n.1.data.id();
        debug!("dataflow_for({:?}, id={:?}) {:?}", e, id, self.variants);
        let mut sets = String::new();
        let mut seen_one = false;
        for &variant in &self.variants {
            if seen_one { sets.push_str(" "); } else { seen_one = true; }
            sets.push_str(variant.short_name());
            sets.push_str(": ");
            sets.push_str(&self.dataflow_for_variant(e, n, variant));
        }
        sets
    }

    fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node<'_>, v: Variant) -> String {
        let cfgidx = n.0;
        match v {
            Loans   => self.dataflow_loans_for(e, cfgidx),
            Moves   => self.dataflow_moves_for(e, cfgidx),
            Assigns => self.dataflow_assigns_for(e, cfgidx),
        }
    }

    fn build_set<O: DataFlowOperator, F>(
        &self,
        e: EntryOrExit,
        cfgidx: CFGIndex,
        dfcx: &DataFlowContext<'tcx, O>,
        mut to_lp: F,
    ) -> String
    where
        F: FnMut(usize) -> Rc<LoanPath<'tcx>>,
    {
        let mut saw_some = false;
        let mut set = "{".to_string();
        dfcx.each_bit_for_node(e, cfgidx, |index| {
            let lp = to_lp(index);
            if saw_some {
                set.push_str(", ");
            }
            let loan_str = self.borrowck_ctxt.loan_path_to_string(&lp);
            set.push_str(&loan_str);
            saw_some = true;
            true
        });
        set.push_str("}");
        set
    }

    fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
        let dfcx = &self.analysis_data.loans;
        let loan_index_to_path = |loan_index| {
            let all_loans = &self.analysis_data.all_loans;
            let l: &borrowck::Loan<'_> = &all_loans[loan_index];
            l.loan_path()
        };
        self.build_set(e, cfgidx, dfcx, loan_index_to_path)
    }

    fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
        let dfcx = &self.analysis_data.move_data.dfcx_moves;
        let move_index_to_path = |move_index| {
            let move_data = &self.analysis_data.move_data.move_data;
            let moves = move_data.moves.borrow();
            let the_move: &borrowck::move_data::Move = &(*moves)[move_index];
            move_data.path_loan_path(the_move.path)
        };
        self.build_set(e, cfgidx, dfcx, move_index_to_path)
    }

    fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
        let dfcx = &self.analysis_data.move_data.dfcx_assign;
        let assign_index_to_path = |assign_index| {
            let move_data = &self.analysis_data.move_data.move_data;
            let assignments = move_data.var_assignments.borrow();
            let assignment: &borrowck::move_data::Assignment = &(*assignments)[assign_index];
            move_data.path_loan_path(assignment.path)
        };
        self.build_set(e, cfgidx, dfcx, assign_index_to_path)
    }
}

impl<'a, 'tcx> dot::Labeller<'a> for DataflowLabeller<'a, 'tcx> {
    type Node = Node<'a>;
    type Edge = Edge<'a>;
    fn graph_id(&'a self) -> dot::Id<'a> { self.inner.graph_id() }
    fn node_id(&'a self, n: &Node<'a>) -> dot::Id<'a> { self.inner.node_id(n) }
    fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> {
        let prefix = self.dataflow_for(EntryOrExit::Entry, n);
        let suffix = self.dataflow_for(EntryOrExit::Exit, n);
        let inner_label = self.inner.node_label(n);
        inner_label
            .prefix_line(dot::LabelText::LabelStr(prefix.into()))
            .suffix_line(dot::LabelText::LabelStr(suffix.into()))
    }
    fn edge_label(&'a self, e: &Edge<'a>) -> dot::LabelText<'a> { self.inner.edge_label(e) }
}

impl<'a, 'tcx> dot::GraphWalk<'a> for DataflowLabeller<'a, 'tcx> {
    type Node = Node<'a>;
    type Edge = Edge<'a>;
    fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
    fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
    fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
    fn target(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
}
