use serde_json::json;

use crate::mir::{BasicBlockId, MirInstruction, ValueId};

pub(crate) fn emit_branch(
    condition: &ValueId,
    then_bb: &BasicBlockId,
    else_bb: &BasicBlockId,
) -> serde_json::Value {
    json!({"op":"branch","cond": condition.as_u32(), "then": then_bb.as_u32(), "else": else_bb.as_u32()})
}

pub(crate) fn emit_jump(target: &BasicBlockId) -> serde_json::Value {
    json!({"op":"jump","target": target.as_u32()})
}

pub(crate) fn emit_return(value: Option<&ValueId>) -> serde_json::Value {
    json!({"op":"ret","value": value.map(|v| v.as_u32())})
}

pub(crate) fn emit_terminator(term: &MirInstruction) -> Option<serde_json::Value> {
    match term {
        MirInstruction::Return { value } => Some(emit_return(value.as_ref())),
        MirInstruction::Jump { target, .. } => Some(emit_jump(target)),
        MirInstruction::Branch {
            condition,
            then_bb,
            else_bb,
            ..
        } => Some(emit_branch(condition, then_bb, else_bb)),
        _ => None,
    }
}
