use std::collections::VecDeque;

use crate::borrow_check::borrow_set::BorrowData;
use crate::borrow_check::error_reporting::UseSpans;
use crate::borrow_check::nll::region_infer::{Cause, RegionName};
use crate::borrow_check::nll::ConstraintDescription;
use crate::borrow_check::{MirBorrowckCtxt, WriteKind};
use rustc::mir::{
    CastKind, ConstraintCategory, FakeReadCause, Local, Location, Body, Operand, Place, PlaceBase,
    Rvalue, Statement, StatementKind, TerminatorKind,
};
use rustc::ty::{self, TyCtxt};
use rustc::ty::adjustment::{PointerCast};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::DiagnosticBuilder;
use syntax_pos::Span;

mod find_use;

pub(in crate::borrow_check) enum BorrowExplanation {
    UsedLater(LaterUseKind, Span),
    UsedLaterInLoop(LaterUseKind, Span),
    UsedLaterWhenDropped {
        drop_loc: Location,
        dropped_local: Local,
        should_note_order: bool,
    },
    MustBeValidFor {
        category: ConstraintCategory,
        from_closure: bool,
        span: Span,
        region_name: RegionName,
        opt_place_desc: Option<String>,
    },
    Unexplained,
}

#[derive(Clone, Copy)]
pub(in crate::borrow_check) enum LaterUseKind {
    TraitCapture,
    ClosureCapture,
    Call,
    FakeLetRead,
    Other,
}

impl BorrowExplanation {
    pub(in crate::borrow_check) fn is_explained(&self) -> bool {
        match self {
            BorrowExplanation::Unexplained => false,
            _ => true,
        }
    }
    pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        body: &Body<'tcx>,
        err: &mut DiagnosticBuilder<'_>,
        borrow_desc: &str,
        borrow_span: Option<Span>,
    ) {
        match *self {
            BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
                let message = match later_use_kind {
                    LaterUseKind::TraitCapture => "captured here by trait object",
                    LaterUseKind::ClosureCapture => "captured here by closure",
                    LaterUseKind::Call => "used by call",
                    LaterUseKind::FakeLetRead => "stored here",
                    LaterUseKind::Other => "used here",
                };
                if !borrow_span.map(|sp| sp.overlaps(var_or_use_span)).unwrap_or(false) {
                    err.span_label(
                        var_or_use_span,
                        format!("{}borrow later {}", borrow_desc, message),
                    );
                }
            }
            BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
                let message = match later_use_kind {
                    LaterUseKind::TraitCapture => {
                        "borrow captured here by trait object, in later iteration of loop"
                    }
                    LaterUseKind::ClosureCapture => {
                        "borrow captured here by closure, in later iteration of loop"
                    }
                    LaterUseKind::Call => "borrow used by call, in later iteration of loop",
                    LaterUseKind::FakeLetRead => "borrow later stored here",
                    LaterUseKind::Other => "borrow used here, in later iteration of loop",
                };
                err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
            }
            BorrowExplanation::UsedLaterWhenDropped {
                drop_loc,
                dropped_local,
                should_note_order,
            } => {
                let local_decl = &body.local_decls[dropped_local];
                let (dtor_desc, type_desc) = match local_decl.ty.sty {
                    // If type is an ADT that implements Drop, then
                    // simplify output by reporting just the ADT name.
                    ty::Adt(adt, _substs) if adt.has_dtor(tcx) && !adt.is_box() => (
                        "`Drop` code",
                        format!("type `{}`", tcx.def_path_str(adt.did)),
                    ),

                    // Otherwise, just report the whole type (and use
                    // the intentionally fuzzy phrase "destructor")
                    ty::Closure(..) => ("destructor", "closure".to_owned()),
                    ty::Generator(..) => ("destructor", "generator".to_owned()),

                    _ => ("destructor", format!("type `{}`", local_decl.ty)),
                };

                match local_decl.name {
                    Some(local_name) if !local_decl.from_compiler_desugaring() => {
                        let message = format!(
                            "{B}borrow might be used here, when `{LOC}` is dropped \
                             and runs the {DTOR} for {TYPE}",
                            B = borrow_desc,
                            LOC = local_name,
                            TYPE = type_desc,
                            DTOR = dtor_desc
                        );
                        err.span_label(body.source_info(drop_loc).span, message);

                        if should_note_order {
                            err.note(
                                "values in a scope are dropped \
                                 in the opposite order they are defined",
                            );
                        }
                    }
                    _ => {
                        err.span_label(
                            local_decl.source_info.span,
                            format!(
                                "a temporary with access to the {B}borrow \
                                 is created here ...",
                                B = borrow_desc
                            ),
                        );
                        let message = format!(
                            "... and the {B}borrow might be used here, \
                             when that temporary is dropped \
                             and runs the {DTOR} for {TYPE}",
                            B = borrow_desc,
                            TYPE = type_desc,
                            DTOR = dtor_desc
                        );
                        err.span_label(body.source_info(drop_loc).span, message);

                        if let Some(info) = &local_decl.is_block_tail {
                            // FIXME: use span_suggestion instead, highlighting the
                            // whole block tail expression.
                            let msg = if info.tail_result_is_ignored {
                                "The temporary is part of an expression at the end of a block. \
                                 Consider adding semicolon after the expression so its temporaries \
                                 are dropped sooner, before the local variables declared by the \
                                 block are dropped."
                            } else {
                                "The temporary is part of an expression at the end of a block. \
                                 Consider forcing this temporary to be dropped sooner, before \
                                 the block's local variables are dropped. \
                                 For example, you could save the expression's value in a new \
                                 local variable `x` and then make `x` be the expression \
                                 at the end of the block."
                            };

                            err.note(msg);
                        }
                    }
                }
            }
            BorrowExplanation::MustBeValidFor {
                category,
                span,
                ref region_name,
                ref opt_place_desc,
                from_closure: _,
            } => {
                region_name.highlight_region_name(err);

                if let Some(desc) = opt_place_desc {
                    err.span_label(
                        span,
                        format!(
                            "{}requires that `{}` is borrowed for `{}`",
                            category.description(),
                            desc,
                            region_name,
                        ),
                    );
                } else {
                    err.span_label(
                        span,
                        format!(
                            "{}requires that {}borrow lasts for `{}`",
                            category.description(),
                            borrow_desc,
                            region_name,
                        ),
                    );
                };
            }
            _ => {}
        }
    }
}

impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
    /// Returns structured explanation for *why* the borrow contains the
    /// point from `location`. This is key for the "3-point errors"
    /// [described in the NLL RFC][d].
    ///
    /// # Parameters
    ///
    /// - `borrow`: the borrow in question
    /// - `location`: where the borrow occurs
    /// - `kind_place`: if Some, this describes the statement that triggered the error.
    ///   - first half is the kind of write, if any, being performed
    ///   - second half is the place being accessed
    ///
    /// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
    pub(in crate::borrow_check) fn explain_why_borrow_contains_point(
        &self,
        location: Location,
        borrow: &BorrowData<'tcx>,
        kind_place: Option<(WriteKind, &Place<'tcx>)>,
    ) -> BorrowExplanation {
        debug!(
            "explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})",
            location, borrow, kind_place
        );

        let regioncx = &self.nonlexical_regioncx;
        let body = self.body;
        let tcx = self.infcx.tcx;

        let borrow_region_vid = borrow.region;
        debug!(
            "explain_why_borrow_contains_point: borrow_region_vid={:?}",
            borrow_region_vid
        );

        let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, location);
        debug!(
            "explain_why_borrow_contains_point: region_sub={:?}",
            region_sub
        );

        match find_use::find(body, regioncx, tcx, region_sub, location) {
            Some(Cause::LiveVar(local, location)) => {
                let span = body.source_info(location).span;
                let spans = self
                    .move_spans(Place::from(local).as_ref(), location)
                    .or_else(|| self.borrow_spans(span, location));

                let borrow_location = location;
                if self.is_use_in_later_iteration_of_loop(borrow_location, location) {
                    let later_use = self.later_use_kind(borrow, spans, location);
                    BorrowExplanation::UsedLaterInLoop(later_use.0, later_use.1)
                } else {
                    // Check if the location represents a `FakeRead`, and adapt the error
                    // message to the `FakeReadCause` it is from: in particular,
                    // the ones inserted in optimized `let var = <expr>` patterns.
                    let later_use = self.later_use_kind(borrow, spans, location);
                    BorrowExplanation::UsedLater(later_use.0, later_use.1)
                }
            }

            Some(Cause::DropVar(local, location)) => {
                let mut should_note_order = false;
                if body.local_decls[local].name.is_some() {
                    if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
                        if let Place {
                            base: PlaceBase::Local(borrowed_local),
                            projection: box [],
                        } = place {
                             if body.local_decls[*borrowed_local].name.is_some()
                                && local != *borrowed_local
                            {
                                should_note_order = true;
                            }
                        }
                    }
                }

                BorrowExplanation::UsedLaterWhenDropped {
                    drop_loc: location,
                    dropped_local: local,
                    should_note_order,
                }
            }

            None => {
                if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) {
                    let (category, from_closure, span, region_name) =
                        self.nonlexical_regioncx.free_region_constraint_info(
                            self.body,
                        &self.upvars,
                            self.mir_def_id,
                            self.infcx,
                            borrow_region_vid,
                            region,
                        );
                    if let Some(region_name) = region_name {
                        let opt_place_desc =
                            self.describe_place(borrow.borrowed_place.as_ref());
                        BorrowExplanation::MustBeValidFor {
                            category,
                            from_closure,
                            span,
                            region_name,
                            opt_place_desc,
                        }
                    } else {
                        debug!("explain_why_borrow_contains_point: \
                                Could not generate a region name");
                        BorrowExplanation::Unexplained
                    }
                } else {
                    debug!("explain_why_borrow_contains_point: \
                            Could not generate an error region vid");
                    BorrowExplanation::Unexplained
                }
            }
        }
    }

    /// true if `borrow_location` can reach `use_location` by going through a loop and
    /// `use_location` is also inside of that loop
    fn is_use_in_later_iteration_of_loop(
        &self,
        borrow_location: Location,
        use_location: Location,
    ) -> bool {
        let back_edge = self.reach_through_backedge(borrow_location, use_location);
        back_edge.map_or(false, |back_edge| {
            self.can_reach_head_of_loop(use_location, back_edge)
        })
    }

    /// Returns the outmost back edge if `from` location can reach `to` location passing through
    /// that back edge
    fn reach_through_backedge(&self, from: Location, to: Location) -> Option<Location> {
        let mut visited_locations = FxHashSet::default();
        let mut pending_locations = VecDeque::new();
        visited_locations.insert(from);
        pending_locations.push_back(from);
        debug!("reach_through_backedge: from={:?} to={:?}", from, to,);

        let mut outmost_back_edge = None;
        while let Some(location) = pending_locations.pop_front() {
            debug!(
                "reach_through_backedge: location={:?} outmost_back_edge={:?}
                   pending_locations={:?} visited_locations={:?}",
                location, outmost_back_edge, pending_locations, visited_locations
            );

            if location == to && outmost_back_edge.is_some() {
                // We've managed to reach the use location
                debug!("reach_through_backedge: found!");
                return outmost_back_edge;
            }

            let block = &self.body.basic_blocks()[location.block];

            if location.statement_index < block.statements.len() {
                let successor = location.successor_within_block();
                if visited_locations.insert(successor) {
                    pending_locations.push_back(successor);
                }
            } else {
                pending_locations.extend(
                    block
                        .terminator()
                        .successors()
                        .map(|bb| Location {
                            statement_index: 0,
                            block: *bb,
                        })
                        .filter(|s| visited_locations.insert(*s))
                        .map(|s| {
                            if self.is_back_edge(location, s) {
                                match outmost_back_edge {
                                    None => {
                                        outmost_back_edge = Some(location);
                                    }

                                    Some(back_edge)
                                        if location.dominates(back_edge, &self.dominators) =>
                                    {
                                        outmost_back_edge = Some(location);
                                    }

                                    Some(_) => {}
                                }
                            }

                            s
                        }),
                );
            }
        }

        None
    }

    /// true if `from` location can reach `loop_head` location and `loop_head` dominates all the
    /// intermediate nodes
    fn can_reach_head_of_loop(&self, from: Location, loop_head: Location) -> bool {
        self.find_loop_head_dfs(from, loop_head, &mut FxHashSet::default())
    }

    fn find_loop_head_dfs(
        &self,
        from: Location,
        loop_head: Location,
        visited_locations: &mut FxHashSet<Location>,
    ) -> bool {
        visited_locations.insert(from);

        if from == loop_head {
            return true;
        }

        if loop_head.dominates(from, &self.dominators) {
            let block = &self.body.basic_blocks()[from.block];

            if from.statement_index < block.statements.len() {
                let successor = from.successor_within_block();

                if !visited_locations.contains(&successor)
                    && self.find_loop_head_dfs(successor, loop_head, visited_locations)
                {
                    return true;
                }
            } else {
                for bb in block.terminator().successors() {
                    let successor = Location {
                        statement_index: 0,
                        block: *bb,
                    };

                    if !visited_locations.contains(&successor)
                        && self.find_loop_head_dfs(successor, loop_head, visited_locations)
                    {
                        return true;
                    }
                }
            }
        }

        false
    }

    /// True if an edge `source -> target` is a backedge -- in other words, if the target
    /// dominates the source.
    fn is_back_edge(&self, source: Location, target: Location) -> bool {
        target.dominates(source, &self.body.dominators())
    }

    /// Determine how the borrow was later used.
    fn later_use_kind(
        &self,
        borrow: &BorrowData<'tcx>,
        use_spans: UseSpans,
        location: Location,
    ) -> (LaterUseKind, Span) {
        match use_spans {
            UseSpans::ClosureUse { var_span, .. } => {
                // Used in a closure.
                (LaterUseKind::ClosureCapture, var_span)
            }
            UseSpans::OtherUse(span) => {
                let block = &self.body.basic_blocks()[location.block];

                let kind = if let Some(&Statement {
                    kind: StatementKind::FakeRead(FakeReadCause::ForLet, _),
                    ..
                }) = block.statements.get(location.statement_index)
                {
                    LaterUseKind::FakeLetRead
                } else if self.was_captured_by_trait_object(borrow) {
                    LaterUseKind::TraitCapture
                } else if location.statement_index == block.statements.len() {
                    if let TerminatorKind::Call {
                        ref func,
                        from_hir_call: true,
                        ..
                    } = block.terminator().kind
                    {
                        // Just point to the function, to reduce the chance of overlapping spans.
                        let function_span = match func {
                            Operand::Constant(c) => c.span,
                            Operand::Copy(Place {
                                base: PlaceBase::Local(l),
                                projection: box [],
                            }) |
                            Operand::Move(Place {
                                base: PlaceBase::Local(l),
                                projection: box [],
                            }) => {
                                let local_decl = &self.body.local_decls[*l];
                                if local_decl.name.is_none() {
                                    local_decl.source_info.span
                                } else {
                                    span
                                }
                            }
                            _ => span,
                        };
                        return (LaterUseKind::Call, function_span);
                    } else {
                        LaterUseKind::Other
                    }
                } else {
                    LaterUseKind::Other
                };

                (kind, span)
            }
        }
    }

    /// Checks if a borrowed value was captured by a trait object. We do this by
    /// looking forward in the MIR from the reserve location and checking if we see
    /// a unsized cast to a trait object on our data.
    fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
        // Start at the reserve location, find the place that we want to see cast to a trait object.
        let location = borrow.reserve_location;
        let block = &self.body[location.block];
        let stmt = block.statements.get(location.statement_index);
        debug!(
            "was_captured_by_trait_object: location={:?} stmt={:?}",
            location, stmt
        );

        // We make a `queue` vector that has the locations we want to visit. As of writing, this
        // will only ever have one item at any given time, but by using a vector, we can pop from
        // it which simplifies the termination logic.
        let mut queue = vec![location];
        let mut target = if let Some(&Statement {
            kind: StatementKind::Assign(box(Place {
                base: PlaceBase::Local(local),
                projection: box [],
            }, _)),
            ..
        }) = stmt
        {
            local
        } else {
            return false;
        };

        debug!(
            "was_captured_by_trait: target={:?} queue={:?}",
            target, queue
        );
        while let Some(current_location) = queue.pop() {
            debug!("was_captured_by_trait: target={:?}", target);
            let block = &self.body[current_location.block];
            // We need to check the current location to find out if it is a terminator.
            let is_terminator = current_location.statement_index == block.statements.len();
            if !is_terminator {
                let stmt = &block.statements[current_location.statement_index];
                debug!("was_captured_by_trait_object: stmt={:?}", stmt);

                // The only kind of statement that we care about is assignments...
                if let StatementKind::Assign(box(place, rvalue)) = &stmt.kind {
                    let into = match place.local_or_deref_local() {
                        Some(into) => into,
                        None => {
                            // Continue at the next location.
                            queue.push(current_location.successor_within_block());
                            continue;
                        }
                    };

                    match rvalue {
                        // If we see a use, we should check whether it is our data, and if so
                        // update the place that we're looking for to that new place.
                        Rvalue::Use(operand) => match operand {
                            Operand::Copy(Place {
                                base: PlaceBase::Local(from),
                                projection: box [],
                            })
                            | Operand::Move(Place {
                                base: PlaceBase::Local(from),
                                projection: box [],
                            })
                                if *from == target =>
                            {
                                target = into;
                            }
                            _ => {}
                        },
                        // If we see a unsized cast, then if it is our data we should check
                        // whether it is being cast to a trait object.
                        Rvalue::Cast(
                            CastKind::Pointer(PointerCast::Unsize), operand, ty
                        ) => match operand {
                            Operand::Copy(Place {
                                base: PlaceBase::Local(from),
                                projection: box [],
                            })
                            | Operand::Move(Place {
                                base: PlaceBase::Local(from),
                                projection: box [],
                            })
                                if *from == target =>
                            {
                                debug!("was_captured_by_trait_object: ty={:?}", ty);
                                // Check the type for a trait object.
                                return match ty.sty {
                                    // `&dyn Trait`
                                    ty::Ref(_, ty, _) if ty.is_trait() => true,
                                    // `Box<dyn Trait>`
                                    _ if ty.is_box() && ty.boxed_ty().is_trait() => true,
                                    // `dyn Trait`
                                    _ if ty.is_trait() => true,
                                    // Anything else.
                                    _ => false,
                                };
                            }
                            _ => return false,
                        },
                        _ => {}
                    }
                }

                // Continue at the next location.
                queue.push(current_location.successor_within_block());
            } else {
                // The only thing we need to do for terminators is progress to the next block.
                let terminator = block.terminator();
                debug!("was_captured_by_trait_object: terminator={:?}", terminator);

                if let TerminatorKind::Call {
                    destination: Some((Place {
                        base: PlaceBase::Local(dest),
                        projection: box [],
                    }, block)),
                    args,
                    ..
                } = &terminator.kind
                {
                    debug!(
                        "was_captured_by_trait_object: target={:?} dest={:?} args={:?}",
                        target, dest, args
                    );
                    // Check if one of the arguments to this function is the target place.
                    let found_target = args.iter().any(|arg| {
                        if let Operand::Move(Place {
                            base: PlaceBase::Local(potential),
                            projection: box [],
                        }) = arg {
                            *potential == target
                        } else {
                            false
                        }
                    });

                    // If it is, follow this to the next block and update the target.
                    if found_target {
                        target = *dest;
                        queue.push(block.start_location());
                    }
                }
            }

            debug!("was_captured_by_trait: queue={:?}", queue);
        }

        // We didn't find anything and ran out of locations to check.
        false
    }
}
