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(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((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
    }
}
