use super::Error;

use super::debug;
use super::graph;
use super::spans;

use debug::{DebugCounters, NESTED_INDENT};
use graph::{BasicCoverageBlock, BcbBranch, CoverageGraph, TraverseCoverageGraphWithLoops};
use spans::CoverageSpan;

use rustc_data_structures::graph::WithNumNodes;
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::coverage::*;

/// Manages the counter and expression indexes/IDs to generate `CoverageKind` components for MIR
/// `Coverage` statements.
pub(super) struct CoverageCounters {
    function_source_hash: u64,
    next_counter_id: u32,
    num_expressions: u32,
    pub debug_counters: DebugCounters,
}

impl CoverageCounters {
    pub fn new(function_source_hash: u64) -> Self {
        Self {
            function_source_hash,
            next_counter_id: CounterValueReference::START.as_u32(),
            num_expressions: 0,
            debug_counters: DebugCounters::new(),
        }
    }

    /// Activate the `DebugCounters` data structures, to provide additional debug formatting
    /// features when formatting `CoverageKind` (counter) values.
    pub fn enable_debug(&mut self) {
        self.debug_counters.enable();
    }

    /// Makes `CoverageKind` `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
    /// indirectly associated with `CoverageSpans`, and returns additional `Expression`s
    /// representing intermediate values.
    pub fn make_bcb_counters(
        &mut self,
        basic_coverage_blocks: &mut CoverageGraph,
        coverage_spans: &Vec<CoverageSpan>,
    ) -> Result<Vec<CoverageKind>, Error> {
        let mut bcb_counters = BcbCounters::new(self, basic_coverage_blocks);
        bcb_counters.make_bcb_counters(coverage_spans)
    }

    fn make_counter<F>(&mut self, debug_block_label_fn: F) -> CoverageKind
    where
        F: Fn() -> Option<String>,
    {
        let counter = CoverageKind::Counter {
            function_source_hash: self.function_source_hash,
            id: self.next_counter(),
        };
        if self.debug_counters.is_enabled() {
            self.debug_counters.add_counter(&counter, (debug_block_label_fn)());
        }
        counter
    }

    fn make_expression<F>(
        &mut self,
        lhs: ExpressionOperandId,
        op: Op,
        rhs: ExpressionOperandId,
        debug_block_label_fn: F,
    ) -> CoverageKind
    where
        F: Fn() -> Option<String>,
    {
        let id = self.next_expression();
        let expression = CoverageKind::Expression { id, lhs, op, rhs };
        if self.debug_counters.is_enabled() {
            self.debug_counters.add_counter(&expression, (debug_block_label_fn)());
        }
        expression
    }

    pub fn make_identity_counter(&mut self, counter_operand: ExpressionOperandId) -> CoverageKind {
        let some_debug_block_label = if self.debug_counters.is_enabled() {
            self.debug_counters.some_block_label(counter_operand).cloned()
        } else {
            None
        };
        self.make_expression(counter_operand, Op::Add, ExpressionOperandId::ZERO, || {
            some_debug_block_label.clone()
        })
    }

    /// Counter IDs start from one and go up.
    fn next_counter(&mut self) -> CounterValueReference {
        assert!(self.next_counter_id < u32::MAX - self.num_expressions);
        let next = self.next_counter_id;
        self.next_counter_id += 1;
        CounterValueReference::from(next)
    }

    /// Expression IDs start from u32::MAX and go down because an Expression can reference
    /// (add or subtract counts) of both Counter regions and Expression regions. The counter
    /// expression operand IDs must be unique across both types.
    fn next_expression(&mut self) -> InjectedExpressionId {
        assert!(self.next_counter_id < u32::MAX - self.num_expressions);
        let next = u32::MAX - self.num_expressions;
        self.num_expressions += 1;
        InjectedExpressionId::from(next)
    }
}

/// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be
/// injected with `CoverageSpan`s. `Expressions` have no runtime overhead, so if a viable expression
/// (adding or subtracting two other counters or expressions) can compute the same result as an
/// embedded counter, an `Expression` should be used.
struct BcbCounters<'a> {
    coverage_counters: &'a mut CoverageCounters,
    basic_coverage_blocks: &'a mut CoverageGraph,
}

impl<'a> BcbCounters<'a> {
    fn new(
        coverage_counters: &'a mut CoverageCounters,
        basic_coverage_blocks: &'a mut CoverageGraph,
    ) -> Self {
        Self { coverage_counters, basic_coverage_blocks }
    }

    /// If two `BasicCoverageBlock`s branch from another `BasicCoverageBlock`, one of the branches
    /// can be counted by `Expression` by subtracting the other branch from the branching
    /// block. Otherwise, the `BasicCoverageBlock` executed the least should have the `Counter`.
    /// One way to predict which branch executes the least is by considering loops. A loop is exited
    /// at a branch, so the branch that jumps to a `BasicCoverageBlock` outside the loop is almost
    /// always executed less than the branch that does not exit the loop.
    ///
    /// Returns any non-code-span expressions created to represent intermediate values (such as to
    /// add two counters so the result can be subtracted from another counter), or an Error with
    /// message for subsequent debugging.
    fn make_bcb_counters(
        &mut self,
        coverage_spans: &[CoverageSpan],
    ) -> Result<Vec<CoverageKind>, Error> {
        debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
        let num_bcbs = self.basic_coverage_blocks.num_nodes();
        let mut collect_intermediate_expressions = Vec::with_capacity(num_bcbs);

        let mut bcbs_with_coverage = BitSet::new_empty(num_bcbs);
        for covspan in coverage_spans {
            bcbs_with_coverage.insert(covspan.bcb);
        }

        // Walk the `CoverageGraph`. For each `BasicCoverageBlock` node with an associated
        // `CoverageSpan`, add a counter. If the `BasicCoverageBlock` branches, add a counter or
        // expression to each branch `BasicCoverageBlock` (if the branch BCB has only one incoming
        // edge) or edge from the branching BCB to the branch BCB (if the branch BCB has multiple
        // incoming edges).
        //
        // The `TraverseCoverageGraphWithLoops` traversal ensures that, when a loop is encountered,
        // all `BasicCoverageBlock` nodes in the loop are visited before visiting any node outside
        // the loop. The `traversal` state includes a `context_stack`, providing a way to know if
        // the current BCB is in one or more nested loops or not.
        let mut traversal = TraverseCoverageGraphWithLoops::new(&self.basic_coverage_blocks);
        while let Some(bcb) = traversal.next(self.basic_coverage_blocks) {
            if bcbs_with_coverage.contains(bcb) {
                debug!("{:?} has at least one `CoverageSpan`. Get or make its counter", bcb);
                let branching_counter_operand =
                    self.get_or_make_counter_operand(bcb, &mut collect_intermediate_expressions)?;

                if self.bcb_needs_branch_counters(bcb) {
                    self.make_branch_counters(
                        &mut traversal,
                        bcb,
                        branching_counter_operand,
                        &mut collect_intermediate_expressions,
                    )?;
                }
            } else {
                debug!(
                    "{:?} does not have any `CoverageSpan`s. A counter will only be added if \
                    and when a covered BCB has an expression dependency.",
                    bcb,
                );
            }
        }

        if traversal.is_complete() {
            Ok(collect_intermediate_expressions)
        } else {
            Error::from_string(format!(
                "`TraverseCoverageGraphWithLoops` missed some `BasicCoverageBlock`s: {:?}",
                traversal.unvisited(),
            ))
        }
    }

    fn make_branch_counters(
        &mut self,
        traversal: &mut TraverseCoverageGraphWithLoops,
        branching_bcb: BasicCoverageBlock,
        branching_counter_operand: ExpressionOperandId,
        collect_intermediate_expressions: &mut Vec<CoverageKind>,
    ) -> Result<(), Error> {
        let branches = self.bcb_branches(branching_bcb);
        debug!(
            "{:?} has some branch(es) without counters:\n  {}",
            branching_bcb,
            branches
                .iter()
                .map(|branch| {
                    format!("{:?}: {:?}", branch, branch.counter(&self.basic_coverage_blocks))
                })
                .collect::<Vec<_>>()
                .join("\n  "),
        );

        // Use the `traversal` state to decide if a subset of the branches exit a loop, making it
        // likely that branch is executed less than branches that do not exit the same loop. In this
        // case, any branch that does not exit the loop (and has not already been assigned a
        // counter) should be counted by expression, if possible. (If a preferred expression branch
        // is not selected based on the loop context, select any branch without an existing
        // counter.)
        let expression_branch = self.choose_preferred_expression_branch(traversal, &branches);

        // Assign a Counter or Expression to each branch, plus additional `Expression`s, as needed,
        // to sum up intermediate results.
        let mut some_sumup_counter_operand = None;
        for branch in branches {
            // Skip the selected `expression_branch`, if any. It's expression will be assigned after
            // all others.
            if branch != expression_branch {
                let branch_counter_operand = if branch.is_only_path_to_target() {
                    debug!(
                        "  {:?} has only one incoming edge (from {:?}), so adding a \
                        counter",
                        branch, branching_bcb
                    );
                    self.get_or_make_counter_operand(
                        branch.target_bcb,
                        collect_intermediate_expressions,
                    )?
                } else {
                    debug!("  {:?} has multiple incoming edges, so adding an edge counter", branch);
                    self.get_or_make_edge_counter_operand(
                        branching_bcb,
                        branch.target_bcb,
                        collect_intermediate_expressions,
                    )?
                };
                if let Some(sumup_counter_operand) =
                    some_sumup_counter_operand.replace(branch_counter_operand)
                {
                    let intermediate_expression = self.coverage_counters.make_expression(
                        branch_counter_operand,
                        Op::Add,
                        sumup_counter_operand,
                        || None,
                    );
                    debug!(
                        "  [new intermediate expression: {}]",
                        self.format_counter(&intermediate_expression)
                    );
                    let intermediate_expression_operand = intermediate_expression.as_operand_id();
                    collect_intermediate_expressions.push(intermediate_expression);
                    some_sumup_counter_operand.replace(intermediate_expression_operand);
                }
            }
        }

        // Assign the final expression to the `expression_branch` by subtracting the total of all
        // other branches from the counter of the branching BCB.
        let sumup_counter_operand =
            some_sumup_counter_operand.expect("sumup_counter_operand should have a value");
        debug!(
            "Making an expression for the selected expression_branch: {:?} \
            (expression_branch predecessors: {:?})",
            expression_branch,
            self.bcb_predecessors(expression_branch.target_bcb),
        );
        let expression = self.coverage_counters.make_expression(
            branching_counter_operand,
            Op::Subtract,
            sumup_counter_operand,
            || Some(format!("{:?}", expression_branch)),
        );
        debug!("{:?} gets an expression: {}", expression_branch, self.format_counter(&expression));
        let bcb = expression_branch.target_bcb;
        if expression_branch.is_only_path_to_target() {
            self.basic_coverage_blocks[bcb].set_counter(expression)?;
        } else {
            self.basic_coverage_blocks[bcb].set_edge_counter_from(branching_bcb, expression)?;
        }
        Ok(())
    }

    fn get_or_make_counter_operand(
        &mut self,
        bcb: BasicCoverageBlock,
        collect_intermediate_expressions: &mut Vec<CoverageKind>,
    ) -> Result<ExpressionOperandId, Error> {
        self.recursive_get_or_make_counter_operand(bcb, collect_intermediate_expressions, 1)
    }

    fn recursive_get_or_make_counter_operand(
        &mut self,
        bcb: BasicCoverageBlock,
        collect_intermediate_expressions: &mut Vec<CoverageKind>,
        debug_indent_level: usize,
    ) -> Result<ExpressionOperandId, Error> {
        // If the BCB already has a counter, return it.
        if let Some(counter_kind) = self.basic_coverage_blocks[bcb].counter() {
            debug!(
                "{}{:?} already has a counter: {}",
                NESTED_INDENT.repeat(debug_indent_level),
                bcb,
                self.format_counter(counter_kind),
            );
            return Ok(counter_kind.as_operand_id());
        }

        // A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`).
        // Also, a BCB that loops back to itself gets a simple `Counter`. This may indicate the
        // program results in a tight infinite loop, but it should still compile.
        let one_path_to_target = self.bcb_has_one_path_to_target(bcb);
        if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) {
            let counter_kind = self.coverage_counters.make_counter(|| Some(format!("{:?}", bcb)));
            if one_path_to_target {
                debug!(
                    "{}{:?} gets a new counter: {}",
                    NESTED_INDENT.repeat(debug_indent_level),
                    bcb,
                    self.format_counter(&counter_kind),
                );
            } else {
                debug!(
                    "{}{:?} has itself as its own predecessor. It can't be part of its own \
                    Expression sum, so it will get its own new counter: {}. (Note, the compiled \
                    code will generate an infinite loop.)",
                    NESTED_INDENT.repeat(debug_indent_level),
                    bcb,
                    self.format_counter(&counter_kind),
                );
            }
            return self.basic_coverage_blocks[bcb].set_counter(counter_kind);
        }

        // A BCB with multiple incoming edges can compute its count by `Expression`, summing up the
        // counters and/or expressions of its incoming edges. This will recursively get or create
        // counters for those incoming edges first, then call `make_expression()` to sum them up,
        // with additional intermediate expressions as needed.
        let mut predecessors = self.bcb_predecessors(bcb).clone().into_iter();
        debug!(
            "{}{:?} has multiple incoming edges and will get an expression that sums them up...",
            NESTED_INDENT.repeat(debug_indent_level),
            bcb,
        );
        let first_edge_counter_operand = self.recursive_get_or_make_edge_counter_operand(
            predecessors.next().unwrap(),
            bcb,
            collect_intermediate_expressions,
            debug_indent_level + 1,
        )?;
        let mut some_sumup_edge_counter_operand = None;
        for predecessor in predecessors {
            let edge_counter_operand = self.recursive_get_or_make_edge_counter_operand(
                predecessor,
                bcb,
                collect_intermediate_expressions,
                debug_indent_level + 1,
            )?;
            if let Some(sumup_edge_counter_operand) =
                some_sumup_edge_counter_operand.replace(edge_counter_operand)
            {
                let intermediate_expression = self.coverage_counters.make_expression(
                    sumup_edge_counter_operand,
                    Op::Add,
                    edge_counter_operand,
                    || None,
                );
                debug!(
                    "{}new intermediate expression: {}",
                    NESTED_INDENT.repeat(debug_indent_level),
                    self.format_counter(&intermediate_expression)
                );
                let intermediate_expression_operand = intermediate_expression.as_operand_id();
                collect_intermediate_expressions.push(intermediate_expression);
                some_sumup_edge_counter_operand.replace(intermediate_expression_operand);
            }
        }
        let counter_kind = self.coverage_counters.make_expression(
            first_edge_counter_operand,
            Op::Add,
            some_sumup_edge_counter_operand.unwrap(),
            || Some(format!("{:?}", bcb)),
        );
        debug!(
            "{}{:?} gets a new counter (sum of predecessor counters): {}",
            NESTED_INDENT.repeat(debug_indent_level),
            bcb,
            self.format_counter(&counter_kind)
        );
        self.basic_coverage_blocks[bcb].set_counter(counter_kind)
    }

    fn get_or_make_edge_counter_operand(
        &mut self,
        from_bcb: BasicCoverageBlock,
        to_bcb: BasicCoverageBlock,
        collect_intermediate_expressions: &mut Vec<CoverageKind>,
    ) -> Result<ExpressionOperandId, Error> {
        self.recursive_get_or_make_edge_counter_operand(
            from_bcb,
            to_bcb,
            collect_intermediate_expressions,
            1,
        )
    }

    fn recursive_get_or_make_edge_counter_operand(
        &mut self,
        from_bcb: BasicCoverageBlock,
        to_bcb: BasicCoverageBlock,
        collect_intermediate_expressions: &mut Vec<CoverageKind>,
        debug_indent_level: usize,
    ) -> Result<ExpressionOperandId, Error> {
        // If the source BCB has only one successor (assumed to be the given target), an edge
        // counter is unnecessary. Just get or make a counter for the source BCB.
        let successors = self.bcb_successors(from_bcb).iter();
        if successors.len() == 1 {
            return self.recursive_get_or_make_counter_operand(
                from_bcb,
                collect_intermediate_expressions,
                debug_indent_level + 1,
            );
        }

        // If the edge already has a counter, return it.
        if let Some(counter_kind) = self.basic_coverage_blocks[to_bcb].edge_counter_from(from_bcb) {
            debug!(
                "{}Edge {:?}->{:?} already has a counter: {}",
                NESTED_INDENT.repeat(debug_indent_level),
                from_bcb,
                to_bcb,
                self.format_counter(counter_kind)
            );
            return Ok(counter_kind.as_operand_id());
        }

        // Make a new counter to count this edge.
        let counter_kind =
            self.coverage_counters.make_counter(|| Some(format!("{:?}->{:?}", from_bcb, to_bcb)));
        debug!(
            "{}Edge {:?}->{:?} gets a new counter: {}",
            NESTED_INDENT.repeat(debug_indent_level),
            from_bcb,
            to_bcb,
            self.format_counter(&counter_kind)
        );
        self.basic_coverage_blocks[to_bcb].set_edge_counter_from(from_bcb, counter_kind)
    }

    /// Select a branch for the expression, either the recommended `reloop_branch`, or if none was
    /// found, select any branch.
    fn choose_preferred_expression_branch(
        &self,
        traversal: &TraverseCoverageGraphWithLoops,
        branches: &[BcbBranch],
    ) -> BcbBranch {
        let branch_needs_a_counter =
            |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();

        let some_reloop_branch = self.find_some_reloop_branch(traversal, &branches);
        if let Some(reloop_branch_without_counter) =
            some_reloop_branch.filter(branch_needs_a_counter)
        {
            debug!(
                "Selecting reloop_branch={:?} that still needs a counter, to get the \
                `Expression`",
                reloop_branch_without_counter
            );
            reloop_branch_without_counter
        } else {
            let &branch_without_counter = branches
                .iter()
                .find(|&&branch| branch.counter(&self.basic_coverage_blocks).is_none())
                .expect(
                    "needs_branch_counters was `true` so there should be at least one \
                    branch",
                );
            debug!(
                "Selecting any branch={:?} that still needs a counter, to get the \
                `Expression` because there was no `reloop_branch`, or it already had a \
                counter",
                branch_without_counter
            );
            branch_without_counter
        }
    }

    /// At most, one of the branches (or its edge, from the branching_bcb, if the branch has
    /// multiple incoming edges) can have a counter computed by expression.
    ///
    /// If at least one of the branches leads outside of a loop (`found_loop_exit` is
    /// true), and at least one other branch does not exit the loop (the first of which
    /// is captured in `some_reloop_branch`), it's likely any reloop branch will be
    /// executed far more often than loop exit branch, making the reloop branch a better
    /// candidate for an expression.
    fn find_some_reloop_branch(
        &self,
        traversal: &TraverseCoverageGraphWithLoops,
        branches: &[BcbBranch],
    ) -> Option<BcbBranch> {
        let branch_needs_a_counter =
            |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();

        let mut some_reloop_branch: Option<BcbBranch> = None;
        for context in traversal.context_stack.iter().rev() {
            if let Some((backedge_from_bcbs, _)) = &context.loop_backedges {
                let mut found_loop_exit = false;
                for &branch in branches.iter() {
                    if backedge_from_bcbs.iter().any(|&backedge_from_bcb| {
                        self.bcb_is_dominated_by(backedge_from_bcb, branch.target_bcb)
                    }) {
                        if let Some(reloop_branch) = some_reloop_branch {
                            if reloop_branch.counter(&self.basic_coverage_blocks).is_none() {
                                // we already found a candidate reloop_branch that still
                                // needs a counter
                                continue;
                            }
                        }
                        // The path from branch leads back to the top of the loop. Set this
                        // branch as the `reloop_branch`. If this branch already has a
                        // counter, and we find another reloop branch that doesn't have a
                        // counter yet, that branch will be selected as the `reloop_branch`
                        // instead.
                        some_reloop_branch = Some(branch);
                    } else {
                        // The path from branch leads outside this loop
                        found_loop_exit = true;
                    }
                    if found_loop_exit
                        && some_reloop_branch.filter(branch_needs_a_counter).is_some()
                    {
                        // Found both a branch that exits the loop and a branch that returns
                        // to the top of the loop (`reloop_branch`), and the `reloop_branch`
                        // doesn't already have a counter.
                        break;
                    }
                }
                if !found_loop_exit {
                    debug!(
                        "No branches exit the loop, so any branch without an existing \
                        counter can have the `Expression`."
                    );
                    break;
                }
                if some_reloop_branch.is_some() {
                    debug!(
                        "Found a branch that exits the loop and a branch the loops back to \
                        the top of the loop (`reloop_branch`). The `reloop_branch` will \
                        get the `Expression`, as long as it still needs a counter."
                    );
                    break;
                }
                // else all branches exited this loop context, so run the same checks with
                // the outer loop(s)
            }
        }
        some_reloop_branch
    }

    #[inline]
    fn bcb_predecessors(&self, bcb: BasicCoverageBlock) -> &Vec<BasicCoverageBlock> {
        &self.basic_coverage_blocks.predecessors[bcb]
    }

    #[inline]
    fn bcb_successors(&self, bcb: BasicCoverageBlock) -> &Vec<BasicCoverageBlock> {
        &self.basic_coverage_blocks.successors[bcb]
    }

    #[inline]
    fn bcb_branches(&self, from_bcb: BasicCoverageBlock) -> Vec<BcbBranch> {
        self.bcb_successors(from_bcb)
            .iter()
            .map(|&to_bcb| BcbBranch::from_to(from_bcb, to_bcb, &self.basic_coverage_blocks))
            .collect::<Vec<_>>()
    }

    fn bcb_needs_branch_counters(&self, bcb: BasicCoverageBlock) -> bool {
        let branch_needs_a_counter =
            |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
        let branches = self.bcb_branches(bcb);
        branches.len() > 1 && branches.iter().any(branch_needs_a_counter)
    }

    /// Returns true if the BasicCoverageBlock has zero or one incoming edge. (If zero, it should be
    /// the entry point for the function.)
    #[inline]
    fn bcb_has_one_path_to_target(&self, bcb: BasicCoverageBlock) -> bool {
        self.bcb_predecessors(bcb).len() <= 1
    }

    #[inline]
    fn bcb_is_dominated_by(&self, node: BasicCoverageBlock, dom: BasicCoverageBlock) -> bool {
        self.basic_coverage_blocks.is_dominated_by(node, dom)
    }

    #[inline]
    fn format_counter(&self, counter_kind: &CoverageKind) -> String {
        self.coverage_counters.debug_counters.format_counter(counter_kind)
    }
}
