use crate::build::matches::MatchPair;
use crate::build::Builder;
use crate::hair::*;
use rustc_middle::mir::*;
use rustc_middle::ty;
use smallvec::SmallVec;
use std::convert::TryInto;

impl<'a, 'tcx> Builder<'a, 'tcx> {
    crate fn field_match_pairs<'pat>(
        &mut self,
        place: Place<'tcx>,
        subpatterns: &'pat [FieldPat<'tcx>],
    ) -> Vec<MatchPair<'pat, 'tcx>> {
        subpatterns
            .iter()
            .map(|fieldpat| {
                let place = self.hir.tcx().mk_place_field(
                    place.clone(),
                    fieldpat.field,
                    fieldpat.pattern.ty,
                );
                MatchPair::new(place, &fieldpat.pattern)
            })
            .collect()
    }

    crate fn prefix_slice_suffix<'pat>(
        &mut self,
        match_pairs: &mut SmallVec<[MatchPair<'pat, 'tcx>; 1]>,
        place: &Place<'tcx>,
        prefix: &'pat [Pat<'tcx>],
        opt_slice: Option<&'pat Pat<'tcx>>,
        suffix: &'pat [Pat<'tcx>],
    ) {
        let tcx = self.hir.tcx();
        let (min_length, exact_size) = match place.ty(&self.local_decls, tcx).ty.kind {
            ty::Array(_, length) => {
                (length.eval_usize(tcx, self.hir.param_env).try_into().unwrap(), true)
            }
            _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
        };

        match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
            let elem =
                ProjectionElem::ConstantIndex { offset: idx as u32, min_length, from_end: false };
            let place = tcx.mk_place_elem(place.clone(), elem);
            MatchPair::new(place, subpattern)
        }));

        if let Some(subslice_pat) = opt_slice {
            let suffix_len = suffix.len() as u32;
            let subslice = tcx.mk_place_elem(
                place.clone(),
                ProjectionElem::Subslice {
                    from: prefix.len() as u32,
                    to: if exact_size { min_length - suffix_len } else { suffix_len },
                    from_end: !exact_size,
                },
            );
            match_pairs.push(MatchPair::new(subslice, subslice_pat));
        }

        match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| {
            let end_offset = (idx + 1) as u32;
            let elem = ProjectionElem::ConstantIndex {
                offset: if exact_size { min_length - end_offset } else { end_offset },
                min_length,
                from_end: !exact_size,
            };
            let place = tcx.mk_place_elem(place.clone(), elem);
            MatchPair::new(place, subpattern)
        }));
    }

    /// Creates a false edge to `imaginary_target` and a real edge to
    /// real_target. If `imaginary_target` is none, or is the same as the real
    /// target, a Goto is generated instead to simplify the generated MIR.
    crate fn false_edges(
        &mut self,
        from_block: BasicBlock,
        real_target: BasicBlock,
        imaginary_target: Option<BasicBlock>,
        source_info: SourceInfo,
    ) {
        match imaginary_target {
            Some(target) if target != real_target => {
                self.cfg.terminate(
                    from_block,
                    source_info,
                    TerminatorKind::FalseEdges { real_target, imaginary_target: target },
                );
            }
            _ => self.cfg.goto(from_block, source_info, real_target),
        }
    }
}

impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
    crate fn new(place: Place<'tcx>, pattern: &'pat Pat<'tcx>) -> MatchPair<'pat, 'tcx> {
        MatchPair { place, pattern }
    }
}
