use codegen::ir::UserFuncName;
use cranelift::prelude::*;
use cranelift_jit::{JITBuilder, JITModule};
use cranelift_module::{default_libcall_names, Linkage, Module};
use std::mem;

fn main() {
    let mut flag_builder = settings::builder();
    flag_builder.set("use_colocated_libcalls", "false").unwrap();
    // FIXME set back to true once the x64 backend supports it.
    flag_builder.set("is_pic", "false").unwrap();
    let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
        panic!("host machine is not supported: {}", msg);
    });
    let isa = isa_builder
        .finish(settings::Flags::new(flag_builder))
        .unwrap();
    let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));

    let mut ctx = module.make_context();
    let mut func_ctx = FunctionBuilderContext::new();

    let mut sig_a = module.make_signature();
    sig_a.params.push(AbiParam::new(types::I32));
    sig_a.returns.push(AbiParam::new(types::I32));

    let mut sig_b = module.make_signature();
    sig_b.returns.push(AbiParam::new(types::I32));

    let func_a = module
        .declare_function("a", Linkage::Local, &sig_a)
        .unwrap();
    let func_b = module
        .declare_function("b", Linkage::Local, &sig_b)
        .unwrap();

    ctx.func.signature = sig_a;
    ctx.func.name = UserFuncName::user(0, func_a.as_u32());

    {
        let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
        let block = bcx.create_block();

        bcx.switch_to_block(block);
        bcx.append_block_params_for_function_params(block);
        let param = bcx.block_params(block)[0];
        let cst = bcx.ins().iconst(types::I32, 37);
        let add = bcx.ins().iadd(cst, param);
        bcx.ins().return_(&[add]);
        bcx.seal_all_blocks();
        bcx.finalize();
    }
    module.define_function(func_a, &mut ctx).unwrap();
    module.clear_context(&mut ctx);

    ctx.func.signature = sig_b;
    ctx.func.name = UserFuncName::user(0, func_b.as_u32());

    {
        let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
        let block = bcx.create_block();

        bcx.switch_to_block(block);
        let local_func = module.declare_func_in_func(func_a, &mut bcx.func);
        let arg = bcx.ins().iconst(types::I32, 5);
        let call = bcx.ins().call(local_func, &[arg]);
        let value = {
            let results = bcx.inst_results(call);
            assert_eq!(results.len(), 1);
            results[0].clone()
        };
        bcx.ins().return_(&[value]);
        bcx.seal_all_blocks();
        bcx.finalize();
    }
    module.define_function(func_b, &mut ctx).unwrap();
    module.clear_context(&mut ctx);

    // Perform linking.
    module.finalize_definitions().unwrap();

    // Get a raw pointer to the generated code.
    let code_b = module.get_finalized_function(func_b);

    // Cast it to a rust function pointer type.
    let ptr_b = unsafe { mem::transmute::<_, extern "C" fn() -> u32>(code_b) };

    // Call it!
    let res = ptr_b();

    assert_eq!(res, 42);
}
