use super::_match::{MatchCheckCtxt, Matrix, expand_pattern, is_useful};
use super::_match::Usefulness::*;
use super::_match::WitnessPreference::*;

use super::{Pattern, PatternContext, PatternError, PatternKind};

use rustc::middle::borrowck::SignalledError;
use rustc::session::Session;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::{InternalSubsts, SubstsRef};
use rustc::lint;
use rustc_errors::{Applicability, DiagnosticBuilder};

use rustc::hir::def::*;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::ptr::P;
use rustc::hir::{self, Pat, PatKind};

use smallvec::smallvec;
use std::slice;

use syntax_pos::{Span, DUMMY_SP, MultiSpan};

crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) -> SignalledError {
    let body_id = if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
        tcx.hir().body_owned_by(id)
    } else {
        return SignalledError::NoErrorsSeen;
    };

    let mut visitor = MatchVisitor {
        tcx,
        tables: tcx.body_tables(body_id),
        param_env: tcx.param_env(def_id),
        identity_substs: InternalSubsts::identity_for_item(tcx, def_id),
        signalled_error: SignalledError::NoErrorsSeen,
    };
    visitor.visit_body(tcx.hir().body(body_id));
    visitor.signalled_error
}

fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBuilder<'_> {
    struct_span_err!(sess, sp, E0004, "{}", &error_message)
}

struct MatchVisitor<'a, 'tcx> {
    tcx: TyCtxt<'tcx>,
    tables: &'a ty::TypeckTables<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    identity_substs: SubstsRef<'tcx>,
    signalled_error: SignalledError,
}

impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
        NestedVisitorMap::None
    }

    fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
        intravisit::walk_expr(self, ex);

        if let hir::ExprKind::Match(ref scrut, ref arms, source) = ex.node {
            self.check_match(scrut, arms, source);
        }
    }

    fn visit_local(&mut self, loc: &'tcx hir::Local) {
        intravisit::walk_local(self, loc);

        self.check_irrefutable(&loc.pat, match loc.source {
            hir::LocalSource::Normal => "local binding",
            hir::LocalSource::ForLoopDesugar => "`for` loop binding",
            hir::LocalSource::AsyncFn => "async fn binding",
            hir::LocalSource::AwaitDesugar => "`await` future binding",
        });

        // Check legality of move bindings and `@` patterns.
        self.check_patterns(false, slice::from_ref(&loc.pat));
    }

    fn visit_body(&mut self, body: &'tcx hir::Body) {
        intravisit::walk_body(self, body);

        for param in &body.params {
            self.check_irrefutable(&param.pat, "function argument");
            self.check_patterns(false, slice::from_ref(&param.pat));
        }
    }
}

impl PatternContext<'_, '_> {
    fn report_inlining_errors(&self, pat_span: Span) {
        for error in &self.errors {
            match *error {
                PatternError::StaticInPattern(span) => {
                    self.span_e0158(span, "statics cannot be referenced in patterns")
                }
                PatternError::AssocConstInPattern(span) => {
                    self.span_e0158(span, "associated consts cannot be referenced in patterns")
                }
                PatternError::FloatBug => {
                    // FIXME(#31407) this is only necessary because float parsing is buggy
                    ::rustc::mir::interpret::struct_error(
                        self.tcx.at(pat_span),
                        "could not evaluate float literal (see issue #31407)",
                    ).emit();
                }
                PatternError::NonConstPath(span) => {
                    ::rustc::mir::interpret::struct_error(
                        self.tcx.at(span),
                        "runtime values cannot be referenced in patterns",
                    ).emit();
                }
            }
        }
    }

    fn span_e0158(&self, span: Span, text: &str) {
        span_err!(self.tcx.sess, span, E0158, "{}", text)
    }
}

impl<'tcx> MatchVisitor<'_, 'tcx> {
    fn check_patterns(&mut self, has_guard: bool, pats: &[P<Pat>]) {
        check_legality_of_move_bindings(self, has_guard, pats);
        for pat in pats {
            check_legality_of_bindings_in_at_patterns(self, pat);
        }
    }

    fn check_match(
        &mut self,
        scrut: &hir::Expr,
        arms: &'tcx [hir::Arm],
        source: hir::MatchSource
    ) {
        for arm in arms {
            // First, check legality of move bindings.
            self.check_patterns(arm.guard.is_some(), &arm.top_pats_hack());

            // Second, if there is a guard on each arm, make sure it isn't
            // assigning or borrowing anything mutably.
            if arm.guard.is_some() {
                self.signalled_error = SignalledError::SawSomeError;
            }

            // Third, perform some lints.
            check_for_bindings_named_same_as_variants(self, &arm.pat);
        }

        let module = self.tcx.hir().get_module_parent(scrut.hir_id);
        MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
            let mut have_errors = false;

            let inlined_arms : Vec<(Vec<_>, _)> = arms.iter().map(|arm| (
                arm.top_pats_hack().iter().map(|pat| {
                    let mut patcx = PatternContext::new(self.tcx,
                                                        self.param_env.and(self.identity_substs),
                                                        self.tables);
                    patcx.include_lint_checks();
                    let pattern = expand_pattern(cx, patcx.lower_pattern(&pat));
                    if !patcx.errors.is_empty() {
                        patcx.report_inlining_errors(pat.span);
                        have_errors = true;
                    }
                    (pattern, &**pat)
                }).collect(),
                arm.guard.as_ref().map(|g| match g {
                    hir::Guard::If(ref e) => &**e,
                })
            )).collect();

            // Bail out early if inlining failed.
            if have_errors {
                return;
            }

            // Fourth, check for unreachable arms.
            check_arms(cx, &inlined_arms, source);

            // Then, if the match has no arms, check whether the scrutinee
            // is uninhabited.
            let pat_ty = self.tables.node_type(scrut.hir_id);
            let module = self.tcx.hir().get_module_parent(scrut.hir_id);
            let mut def_span = None;
            let mut missing_variants = vec![];
            if inlined_arms.is_empty() {
                let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns {
                    self.tcx.is_ty_uninhabited_from(module, pat_ty)
                } else {
                    match pat_ty.sty {
                        ty::Never => true,
                        ty::Adt(def, _) => {
                            def_span = self.tcx.hir().span_if_local(def.did);
                            if def.variants.len() < 4 && !def.variants.is_empty() {
                                // keep around to point at the definition of non-covered variants
                                missing_variants = def.variants.iter()
                                    .map(|variant| variant.ident)
                                    .collect();
                            }

                            let is_non_exhaustive_and_non_local =
                                def.is_variant_list_non_exhaustive() && !def.did.is_local();

                            !(is_non_exhaustive_and_non_local) && def.variants.is_empty()
                        },
                        _ => false
                    }
                };
                if !scrutinee_is_uninhabited {
                    // We know the type is inhabited, so this must be wrong
                    let mut err = create_e0004(
                        self.tcx.sess,
                        scrut.span,
                        format!("non-exhaustive patterns: {}", match missing_variants.len() {
                            0 => format!("type `{}` is non-empty", pat_ty),
                            1 => format!(
                                "pattern `{}` of type `{}` is not handled",
                                missing_variants[0].name,
                                pat_ty,
                            ),
                            _ => format!("multiple patterns of type `{}` are not handled", pat_ty),
                        }),
                    );
                    err.help("ensure that all possible cases are being handled, \
                              possibly by adding wildcards or more match arms");
                    if let Some(sp) = def_span {
                        err.span_label(sp, format!("`{}` defined here", pat_ty));
                    }
                    // point at the definition of non-covered enum variants
                    for variant in &missing_variants {
                        err.span_label(variant.span, "variant not covered");
                    }
                    err.emit();
                }
                // If the type *is* uninhabited, it's vacuously exhaustive
                return;
            }

            let matrix: Matrix<'_, '_> = inlined_arms
                .iter()
                .filter(|&&(_, guard)| guard.is_none())
                .flat_map(|arm| &arm.0)
                .map(|pat| smallvec![pat.0])
                .collect();
            let scrut_ty = self.tables.node_type(scrut.hir_id);
            check_exhaustive(cx, scrut_ty, scrut.span, &matrix);
        })
    }

    fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) {
        let module = self.tcx.hir().get_module_parent(pat.hir_id);
        MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
            let mut patcx = PatternContext::new(self.tcx,
                                                self.param_env.and(self.identity_substs),
                                                self.tables);
            patcx.include_lint_checks();
            let pattern = patcx.lower_pattern(pat);
            let pattern_ty = pattern.ty;
            let pats: Matrix<'_, '_> = vec![smallvec![
                expand_pattern(cx, pattern)
            ]].into_iter().collect();

            let witnesses = match check_not_useful(cx, pattern_ty, &pats) {
                Ok(_) => return,
                Err(err) => err,
            };

            let joined_patterns = joined_uncovered_patterns(&witnesses);
            let mut err = struct_span_err!(
                self.tcx.sess, pat.span, E0005,
                "refutable pattern in {}: {} not covered",
                origin, joined_patterns
            );
            err.span_label(pat.span, match &pat.node {
                PatKind::Path(hir::QPath::Resolved(None, path))
                    if path.segments.len() == 1 && path.segments[0].args.is_none() => {
                    format!("interpreted as {} {} pattern, not new variable",
                            path.res.article(), path.res.descr())
                }
                _ => pattern_not_convered_label(&witnesses, &joined_patterns),
            });
            adt_defined_here(cx, &mut err, pattern_ty, &witnesses);
            err.emit();
        });
    }
}

fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
    pat.walk(|p| {
        if let PatKind::Binding(_, _, ident, None) = p.node {
            if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
                if bm != ty::BindByValue(hir::MutImmutable) {
                    // Nothing to check.
                    return true;
                }
                let pat_ty = cx.tables.pat_ty(p);
                if let ty::Adt(edef, _) = pat_ty.sty {
                    if edef.is_enum() && edef.variants.iter().any(|variant| {
                        variant.ident == ident && variant.ctor_kind == CtorKind::Const
                    }) {
                        let ty_path = cx.tcx.def_path_str(edef.did);
                        let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
                            "pattern binding `{}` is named the same as one \
                            of the variants of the type `{}`",
                            ident, ty_path);
                        err.span_suggestion(
                            p.span,
                            "to match on the variant, qualify the path",
                            format!("{}::{}", ty_path, ident),
                            Applicability::MachineApplicable
                        );
                        err.emit();
                    }
                }
            } else {
                cx.tcx.sess.delay_span_bug(p.span, "missing binding mode");
            }
        }
        true
    });
}

/// Checks for common cases of "catchall" patterns that may not be intended as such.
fn pat_is_catchall(pat: &Pat) -> bool {
    match pat.node {
        PatKind::Binding(.., None) => true,
        PatKind::Binding(.., Some(ref s)) => pat_is_catchall(s),
        PatKind::Ref(ref s, _) => pat_is_catchall(s),
        PatKind::Tuple(ref v, _) => v.iter().all(|p| {
            pat_is_catchall(&p)
        }),
        _ => false
    }
}

// Check for unreachable patterns
fn check_arms<'tcx>(
    cx: &mut MatchCheckCtxt<'_, 'tcx>,
    arms: &[(Vec<(&Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)],
    source: hir::MatchSource,
) {
    let mut seen = Matrix::empty();
    let mut catchall = None;
    for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
        for &(pat, hir_pat) in pats {
            let v = smallvec![pat];

            match is_useful(cx, &seen, &v, LeaveOutWitness) {
                NotUseful => {
                    match source {
                        hir::MatchSource::IfDesugar { .. } |
                        hir::MatchSource::WhileDesugar => bug!(),
                        hir::MatchSource::IfLetDesugar { .. } => {
                            cx.tcx.lint_hir(
                                lint::builtin::IRREFUTABLE_LET_PATTERNS,
                                hir_pat.hir_id,
                                pat.span,
                                "irrefutable if-let pattern",
                            );
                        }

                        hir::MatchSource::WhileLetDesugar => {
                            // check which arm we're on.
                            match arm_index {
                                // The arm with the user-specified pattern.
                                0 => {
                                    cx.tcx.lint_hir(
                                        lint::builtin::UNREACHABLE_PATTERNS,
                                        hir_pat.hir_id, pat.span,
                                        "unreachable pattern");
                                },
                                // The arm with the wildcard pattern.
                                1 => {
                                    cx.tcx.lint_hir(
                                        lint::builtin::IRREFUTABLE_LET_PATTERNS,
                                        hir_pat.hir_id,
                                        pat.span,
                                        "irrefutable while-let pattern",
                                    );
                                },
                                _ => bug!(),
                            }
                        }

                        hir::MatchSource::ForLoopDesugar |
                        hir::MatchSource::Normal => {
                            let mut err = cx.tcx.struct_span_lint_hir(
                                lint::builtin::UNREACHABLE_PATTERNS,
                                hir_pat.hir_id,
                                pat.span,
                                "unreachable pattern",
                            );
                            // if we had a catchall pattern, hint at that
                            if let Some(catchall) = catchall {
                                err.span_label(pat.span, "unreachable pattern");
                                err.span_label(catchall, "matches any value");
                            }
                            err.emit();
                        }

                        // Unreachable patterns in try and await expressions occur when one of
                        // the arms are an uninhabited type. Which is OK.
                        hir::MatchSource::AwaitDesugar |
                        hir::MatchSource::TryDesugar => {}
                    }
                }
                Useful => (),
                UsefulWithWitness(_) => bug!()
            }
            if guard.is_none() {
                seen.push(v);
                if catchall.is_none() && pat_is_catchall(hir_pat) {
                    catchall = Some(pat.span);
                }
            }
        }
    }
}

fn check_not_useful(
    cx: &mut MatchCheckCtxt<'_, 'tcx>,
    ty: Ty<'tcx>,
    matrix: &Matrix<'_, 'tcx>,
) -> Result<(), Vec<Pattern<'tcx>>> {
    let wild_pattern = Pattern { ty, span: DUMMY_SP, kind: box PatternKind::Wild };
    match is_useful(cx, matrix, &[&wild_pattern], ConstructWitness) {
        NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable.
        UsefulWithWitness(pats) => Err(if pats.is_empty() {
            vec![wild_pattern]
        } else {
            pats.into_iter().map(|w| w.single_pattern()).collect()
        }),
        Useful => bug!(),
    }
}

fn check_exhaustive<'tcx>(
    cx: &mut MatchCheckCtxt<'_, 'tcx>,
    scrut_ty: Ty<'tcx>,
    sp: Span,
    matrix: &Matrix<'_, 'tcx>,
) {
    let witnesses = match check_not_useful(cx, scrut_ty, matrix) {
        Ok(_) => return,
        Err(err) => err,
    };

    let joined_patterns = joined_uncovered_patterns(&witnesses);
    let mut err = create_e0004(
        cx.tcx.sess, sp,
        format!("non-exhaustive patterns: {} not covered", joined_patterns),
    );
    err.span_label(sp, pattern_not_convered_label(&witnesses, &joined_patterns));
    adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
    err.help(
        "ensure that all possible cases are being handled, \
        possibly by adding wildcards or more match arms"
    )
    .emit();
}

fn joined_uncovered_patterns(witnesses: &[Pattern<'_>]) -> String {
    const LIMIT: usize = 3;
    match witnesses {
        [] => bug!(),
        [witness] => format!("`{}`", witness),
        [head @ .., tail] if head.len() < LIMIT => {
            let head: Vec<_> = head.iter().map(<_>::to_string).collect();
            format!("`{}` and `{}`", head.join("`, `"), tail)
        }
        _ => {
            let (head, tail) = witnesses.split_at(LIMIT);
            let head: Vec<_> = head.iter().map(<_>::to_string).collect();
            format!("`{}` and {} more", head.join("`, `"), tail.len())
        }
    }
}

fn pattern_not_convered_label(witnesses: &[Pattern<'_>], joined_patterns: &str) -> String {
    format!("pattern{} {} not covered", rustc_errors::pluralise!(witnesses.len()), joined_patterns)
}

/// Point at the definition of non-covered `enum` variants.
fn adt_defined_here(
    cx: &MatchCheckCtxt<'_, '_>,
    err: &mut DiagnosticBuilder<'_>,
    ty: Ty<'_>,
    witnesses: &[Pattern<'_>],
) {
    let ty = ty.peel_refs();
    if let ty::Adt(def, _) = ty.sty {
        if let Some(sp) = cx.tcx.hir().span_if_local(def.did) {
            err.span_label(sp, format!("`{}` defined here", ty));
        }

        if witnesses.len() < 4 {
            for sp in maybe_point_at_variant(ty, &witnesses) {
                err.span_label(sp, "not covered");
            }
        }
    }
}

fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[Pattern<'_>]) -> Vec<Span> {
    let mut covered = vec![];
    if let ty::Adt(def, _) = ty.sty {
        // Don't point at variants that have already been covered due to other patterns to avoid
        // visual clutter.
        for pattern in patterns {
            use PatternKind::{AscribeUserType, Deref, Variant, Or, Leaf};
            match &*pattern.kind {
                AscribeUserType { subpattern, .. } | Deref { subpattern } => {
                    covered.extend(maybe_point_at_variant(ty, slice::from_ref(&subpattern)));
                }
                Variant { adt_def, variant_index, subpatterns, .. } if adt_def.did == def.did => {
                    let sp = def.variants[*variant_index].ident.span;
                    if covered.contains(&sp) {
                        continue;
                    }
                    covered.push(sp);

                    let pats = subpatterns.iter()
                        .map(|field_pattern| field_pattern.pattern.clone())
                        .collect::<Box<[_]>>();
                    covered.extend(maybe_point_at_variant(ty, &pats));
                }
                Leaf { subpatterns } => {
                    let pats = subpatterns.iter()
                        .map(|field_pattern| field_pattern.pattern.clone())
                        .collect::<Box<[_]>>();
                    covered.extend(maybe_point_at_variant(ty, &pats));
                }
                Or { pats } => {
                    let pats = pats.iter().cloned().collect::<Box<[_]>>();
                    covered.extend(maybe_point_at_variant(ty, &pats));
                }
                _ => {}
            }
        }
    }
    covered
}

// Legality of move bindings checking
fn check_legality_of_move_bindings(
    cx: &mut MatchVisitor<'_, '_>,
    has_guard: bool,
    pats: &[P<Pat>],
) {
    let mut by_ref_span = None;
    for pat in pats {
        pat.each_binding(|_, hir_id, span, _path| {
            if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) {
                if let ty::BindByReference(..) = bm {
                    by_ref_span = Some(span);
                }
            } else {
                cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
            }
        })
    }

    let span_vec = &mut Vec::new();
    let mut check_move = |p: &Pat, sub: Option<&Pat>| {
        // Check legality of moving out of the enum.
        //
        // `x @ Foo(..)` is legal, but `x @ Foo(y)` isn't.
        if sub.map_or(false, |p| p.contains_bindings()) {
            struct_span_err!(cx.tcx.sess, p.span, E0007, "cannot bind by-move with sub-bindings")
                .span_label(p.span, "binds an already bound by-move value by moving it")
                .emit();
        } else if !has_guard && by_ref_span.is_some() {
            span_vec.push(p.span);
        }
    };

    for pat in pats {
        pat.walk(|p| {
            if let PatKind::Binding(.., sub) = &p.node {
                if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
                    if let ty::BindByValue(..) = bm {
                        let pat_ty = cx.tables.node_type(p.hir_id);
                        if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) {
                            check_move(p, sub.as_deref());
                        }
                    }
                } else {
                    cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode");
                }
            }
            true
        });
    }
    if !span_vec.is_empty() {
        let mut err = struct_span_err!(
            cx.tcx.sess,
            MultiSpan::from_spans(span_vec.clone()),
            E0009,
            "cannot bind by-move and by-ref in the same pattern",
        );
        if let Some(by_ref_span) = by_ref_span {
            err.span_label(by_ref_span, "both by-ref and by-move used");
        }
        for span in span_vec.iter(){
            err.span_label(*span, "by-move pattern here");
        }
        err.emit();
    }
}

/// Forbids bindings in `@` patterns. This is necessary for memory safety,
/// because of the way rvalues are handled in the borrow check. (See issue
/// #14587.)
fn check_legality_of_bindings_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat) {
    AtBindingPatternVisitor { cx, bindings_allowed: true }.visit_pat(pat);
}

struct AtBindingPatternVisitor<'a, 'b, 'tcx> {
    cx: &'a MatchVisitor<'b, 'tcx>,
    bindings_allowed: bool
}

impl<'v> Visitor<'v> for AtBindingPatternVisitor<'_, '_, '_> {
    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
        NestedVisitorMap::None
    }

    fn visit_pat(&mut self, pat: &Pat) {
        match pat.node {
            PatKind::Binding(.., ref subpat) => {
                if !self.bindings_allowed {
                    struct_span_err!(self.cx.tcx.sess, pat.span, E0303,
                                     "pattern bindings are not allowed after an `@`")
                        .span_label(pat.span,  "not allowed after `@`")
                        .emit();
                }

                if subpat.is_some() {
                    let bindings_were_allowed = self.bindings_allowed;
                    self.bindings_allowed = false;
                    intravisit::walk_pat(self, pat);
                    self.bindings_allowed = bindings_were_allowed;
                }
            }
            _ => intravisit::walk_pat(self, pat),
        }
    }
}
