use crate::hair::cx::to_ref::ToRef;
use crate::hair::cx::Cx;
use crate::hair::{self, *};

use rustc::middle::region;
use rustc::ty;
use rustc_hir as hir;

use rustc_index::vec::Idx;

impl<'tcx> Mirror<'tcx> for &'tcx hir::Block<'tcx> {
    type Output = Block<'tcx>;

    fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Block<'tcx> {
        // We have to eagerly lower the "spine" of the statements
        // in order to get the lexical scoping correctly.
        let stmts = mirror_stmts(cx, self.hir_id.local_id, &*self.stmts);
        let opt_destruction_scope =
            cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id);
        Block {
            targeted_by_break: self.targeted_by_break,
            region_scope: region::Scope { id: self.hir_id.local_id, data: region::ScopeData::Node },
            opt_destruction_scope,
            span: self.span,
            stmts,
            expr: self.expr.to_ref(),
            safety_mode: match self.rules {
                hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe,
                hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(self.hir_id),
                hir::BlockCheckMode::PushUnsafeBlock(..) => BlockSafety::PushUnsafe,
                hir::BlockCheckMode::PopUnsafeBlock(..) => BlockSafety::PopUnsafe,
            },
        }
    }
}

fn mirror_stmts<'a, 'tcx>(
    cx: &mut Cx<'a, 'tcx>,
    block_id: hir::ItemLocalId,
    stmts: &'tcx [hir::Stmt<'tcx>],
) -> Vec<StmtRef<'tcx>> {
    let mut result = vec![];
    for (index, stmt) in stmts.iter().enumerate() {
        let hir_id = stmt.hir_id;
        let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
        match stmt.kind {
            hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
                result.push(StmtRef::Mirror(Box::new(Stmt {
                    kind: StmtKind::Expr {
                        scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node },
                        expr: expr.to_ref(),
                    },
                    opt_destruction_scope: opt_dxn_ext,
                })))
            }
            hir::StmtKind::Item(..) => {
                // ignore for purposes of the MIR
            }
            hir::StmtKind::Local(ref local) => {
                let remainder_scope = region::Scope {
                    id: block_id,
                    data: region::ScopeData::Remainder(region::FirstStatementIndex::new(index)),
                };

                let mut pattern = cx.pattern_from_hir(&local.pat);

                if let Some(ty) = &local.ty {
                    if let Some(&user_ty) = cx.tables.user_provided_types().get(ty.hir_id) {
                        debug!("mirror_stmts: user_ty={:?}", user_ty);
                        pattern = Pat {
                            ty: pattern.ty,
                            span: pattern.span,
                            kind: Box::new(PatKind::AscribeUserType {
                                ascription: hair::pattern::Ascription {
                                    user_ty: PatTyProj::from_user_type(user_ty),
                                    user_ty_span: ty.span,
                                    variance: ty::Variance::Covariant,
                                },
                                subpattern: pattern,
                            }),
                        };
                    }
                }

                result.push(StmtRef::Mirror(Box::new(Stmt {
                    kind: StmtKind::Let {
                        remainder_scope: remainder_scope,
                        init_scope: region::Scope {
                            id: hir_id.local_id,
                            data: region::ScopeData::Node,
                        },
                        pattern,
                        initializer: local.init.to_ref(),
                        lint_level: LintLevel::Explicit(local.hir_id),
                    },
                    opt_destruction_scope: opt_dxn_ext,
                })));
            }
        }
    }
    return result;
}

crate fn to_expr_ref<'a, 'tcx>(
    cx: &mut Cx<'a, 'tcx>,
    block: &'tcx hir::Block<'tcx>,
) -> ExprRef<'tcx> {
    let block_ty = cx.tables().node_type(block.hir_id);
    let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
    let expr = Expr {
        ty: block_ty,
        temp_lifetime,
        span: block.span,
        kind: ExprKind::Block { body: block },
    };
    expr.to_ref()
}
