use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use tracing::trace;

use crate::patch::MirPatch;

pub(super) enum SimplifyConstCondition {
    AfterInstSimplify,
    AfterConstProp,
    Final,
}

/// A pass that replaces a branch with a goto when its condition is known.
impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
    fn name(&self) -> &'static str {
        match self {
            SimplifyConstCondition::AfterInstSimplify => {
                "SimplifyConstCondition-after-inst-simplify"
            }
            SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop",
            SimplifyConstCondition::Final => "SimplifyConstCondition-final",
        }
    }

    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
        trace!("Running SimplifyConstCondition on {:?}", body.source);
        let typing_env = body.typing_env(tcx);
        let mut patch = MirPatch::new(body);

        fn try_get_const<'tcx, 'a>(
            operand: &'a Operand<'tcx>,
            has_place_const: Option<(Place<'tcx>, &'a ConstOperand<'tcx>)>,
        ) -> Option<&'a ConstOperand<'tcx>> {
            match operand {
                Operand::Constant(const_operand) => Some(const_operand),
                // `has_place_const` must be the LHS of the previous statement.
                // Soundness: There is nothing can modify the place, as there are no statements between the two statements.
                Operand::Copy(place) | Operand::Move(place)
                    if let Some((place_const, const_operand)) = has_place_const
                        && place_const == *place =>
                {
                    Some(const_operand)
                }
                Operand::Copy(_) | Operand::Move(_) | Operand::RuntimeChecks(_) => None,
            }
        }

        'blocks: for (bb, block) in body.basic_blocks.iter_enumerated() {
            let mut pre_place_const: Option<(Place<'tcx>, &ConstOperand<'tcx>)> = None;

            for (statement_index, stmt) in block.statements.iter().enumerate() {
                let has_place_const = pre_place_const.take();
                // Simplify `assume` of a known value: either a NOP or unreachable.
                if let StatementKind::Intrinsic(box ref intrinsic) = stmt.kind
                    && let NonDivergingIntrinsic::Assume(discr) = intrinsic
                    && let Some(c) = try_get_const(discr, has_place_const)
                    && let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
                {
                    if constant {
                        patch.nop_statement(Location { block: bb, statement_index });
                    } else {
                        patch.patch_terminator(bb, TerminatorKind::Unreachable);
                        continue 'blocks;
                    }
                } else if let StatementKind::Assign(box (lhs, ref rvalue)) = stmt.kind
                    && let Rvalue::Use(Operand::Constant(c)) = rvalue
                {
                    pre_place_const = Some((lhs, c));
                }
            }

            let terminator = block.terminator();
            let terminator = match terminator.kind {
                TerminatorKind::SwitchInt { ref discr, ref targets, .. }
                    if let Some(c) = try_get_const(discr, pre_place_const.take())
                        && let Some(constant) = c.const_.try_eval_bits(tcx, typing_env) =>
                {
                    let target = targets.target_for_value(constant);
                    TerminatorKind::Goto { target }
                }
                TerminatorKind::Assert { target, ref cond, expected, .. }
                    if let Some(c) = try_get_const(&cond, pre_place_const.take())
                        && let Some(constant) = c.const_.try_eval_bool(tcx, typing_env)
                        && constant == expected =>
                {
                    TerminatorKind::Goto { target }
                }
                _ => continue,
            };
            patch.patch_terminator(bb, terminator);
        }
        patch.apply(body);
    }

    fn is_required(&self) -> bool {
        false
    }
}
