use crate::borrow_check::nll::region_infer::RegionInferenceContext;
use crate::borrow_check::nll::ToRegionVid;
use crate::borrow_check::Upvar;
use rustc::mir::{Local, Body};
use rustc::ty::{RegionVid, TyCtxt};
use rustc_index::vec::{Idx, IndexVec};
use syntax::source_map::Span;
use syntax_pos::symbol::Symbol;

impl<'tcx> RegionInferenceContext<'tcx> {
    crate fn get_var_name_and_span_for_region(
        &self,
        tcx: TyCtxt<'tcx>,
        body: &Body<'tcx>,
        local_names: &IndexVec<Local, Option<Symbol>>,
        upvars: &[Upvar],
        fr: RegionVid,
    ) -> Option<(Option<Symbol>, Span)> {
        debug!("get_var_name_and_span_for_region(fr={:?})", fr);
        assert!(self.universal_regions.is_universal_region(fr));

        debug!("get_var_name_and_span_for_region: attempting upvar");
        self.get_upvar_index_for_region(tcx, fr)
            .map(|index| {
                let (name, span) =
                    self.get_upvar_name_and_span_for_region(tcx, upvars, index);
                (Some(name), span)
            })
            .or_else(|| {
                debug!("get_var_name_and_span_for_region: attempting argument");
                self.get_argument_index_for_region(tcx, fr).map(|index| {
                    self.get_argument_name_and_span_for_region(body, local_names, index)
                })
            })
    }

    /// Search the upvars (if any) to find one that references fr. Return its index.
    crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option<usize> {
        let upvar_index = self
            .universal_regions
            .defining_ty
            .upvar_tys(tcx)
            .position(|upvar_ty| {
                debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty);
                tcx.any_free_region_meets(&upvar_ty, |r| {
                    let r = r.to_region_vid();
                    debug!("get_upvar_index_for_region: r={:?} fr={:?}", r, fr);
                    r == fr
                })
            })?;

        let upvar_ty = self
            .universal_regions
            .defining_ty
            .upvar_tys(tcx)
            .nth(upvar_index);

        debug!(
            "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
            fr, upvar_index, upvar_ty,
        );

        Some(upvar_index)
    }

    /// Given the index of an upvar, finds its name and the span from where it was
    /// declared.
    crate fn get_upvar_name_and_span_for_region(
        &self,
        tcx: TyCtxt<'tcx>,
        upvars: &[Upvar],
        upvar_index: usize,
    ) -> (Symbol, Span) {
        let upvar_hir_id = upvars[upvar_index].var_hir_id;
        debug!("get_upvar_name_and_span_for_region: upvar_hir_id={:?}", upvar_hir_id);

        let upvar_name = tcx.hir().name(upvar_hir_id);
        let upvar_span = tcx.hir().span(upvar_hir_id);
        debug!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
               upvar_name, upvar_span);

        (upvar_name, upvar_span)
    }

    /// Search the argument types for one that references fr (which should be a free region).
    /// Returns Some(_) with the index of the input if one is found.
    ///
    /// N.B., in the case of a closure, the index is indexing into the signature as seen by the
    /// user - in particular, index 0 is not the implicit self parameter.
    crate fn get_argument_index_for_region(
        &self,
        tcx: TyCtxt<'tcx>,
        fr: RegionVid,
    ) -> Option<usize> {
        let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
        let argument_index = self
            .universal_regions
            .unnormalized_input_tys
            .iter()
            .skip(implicit_inputs)
            .position(|arg_ty| {
                debug!(
                    "get_argument_index_for_region: arg_ty = {:?}",
                    arg_ty
                );
                tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
            })?;

        debug!(
            "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
            fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
        );

        Some(argument_index)
    }

    /// Given the index of an argument, finds its name (if any) and the span from where it was
    /// declared.
    crate fn get_argument_name_and_span_for_region(
        &self,
        body: &Body<'tcx>,
        local_names: &IndexVec<Local, Option<Symbol>>,
        argument_index: usize,
    ) -> (Option<Symbol>, Span) {
        let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
        let argument_local = Local::new(implicit_inputs + argument_index + 1);
        debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);

        let argument_name = local_names[argument_local];
        let argument_span = body.local_decls[argument_local].source_info.span;
        debug!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
               argument_name, argument_span);

        (argument_name, argument_span)
    }
}
