use libc::c_uint;
use rustc_ast::expand::allocator::{
    AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, SpecialAllocatorMethod,
    default_fn_name, global_fn_name,
};
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::ty::TyCtxt;
use rustc_session::config::DebugInfo;
use rustc_symbol_mangling::mangle_internal_symbol;

use crate::attributes::llfn_attrs_from_instance;
use crate::builder::SBuilder;
use crate::declare::declare_simple_fn;
use crate::llvm::{self, FromGeneric, TRUE, Type};
use crate::{SimpleCx, attributes, debuginfo};

pub(crate) unsafe fn codegen(
    tcx: TyCtxt<'_>,
    cx: SimpleCx<'_>,
    module_name: &str,
    methods: &[AllocatorMethod],
) {
    let usize = match tcx.sess.target.pointer_width {
        16 => cx.type_i16(),
        32 => cx.type_i32(),
        64 => cx.type_i64(),
        tws => bug!("Unsupported target word size for int: {}", tws),
    };
    let i8p = cx.type_ptr();

    for method in methods {
        let mut args = Vec::with_capacity(method.inputs.len());
        for input in method.inputs.iter() {
            match input.ty {
                AllocatorTy::Layout => {
                    args.push(usize); // size
                    args.push(usize); // align
                }
                AllocatorTy::Ptr => args.push(i8p),
                AllocatorTy::Usize => args.push(usize),

                AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => {
                    panic!("invalid allocator arg")
                }
            }
        }

        let mut no_return = false;
        let output = match method.output {
            AllocatorTy::ResultPtr => Some(i8p),
            AllocatorTy::Unit => None,
            AllocatorTy::Never => {
                no_return = true;
                None
            }

            AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
                panic!("invalid allocator output")
            }
        };

        let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
        let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));

        let alloc_attr_flag = match method.special {
            Some(SpecialAllocatorMethod::Alloc) => CodegenFnAttrFlags::ALLOCATOR,
            Some(SpecialAllocatorMethod::Dealloc) => CodegenFnAttrFlags::DEALLOCATOR,
            Some(SpecialAllocatorMethod::Realloc) => CodegenFnAttrFlags::REALLOCATOR,
            Some(SpecialAllocatorMethod::AllocZeroed) => CodegenFnAttrFlags::ALLOCATOR_ZEROED,
            None => CodegenFnAttrFlags::empty(),
        };

        let mut attrs = CodegenFnAttrs::new();
        attrs.flags |= alloc_attr_flag;
        create_wrapper_function(
            tcx,
            &cx,
            &from_name,
            Some(&to_name),
            &args,
            output,
            no_return,
            &attrs,
        );
    }

    // __rust_no_alloc_shim_is_unstable_v2
    create_wrapper_function(
        tcx,
        &cx,
        &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
        None,
        &[],
        None,
        false,
        &CodegenFnAttrs::new(),
    );

    if tcx.sess.opts.debuginfo != DebugInfo::None {
        let dbg_cx = debuginfo::CodegenUnitDebugContext::new(cx.llmod, tcx.sess);
        debuginfo::metadata::build_compile_unit_di_node(tcx, module_name, &dbg_cx);
        dbg_cx.finalize();
    }
}

fn create_wrapper_function(
    tcx: TyCtxt<'_>,
    cx: &SimpleCx<'_>,
    from_name: &str,
    to_name: Option<&str>,
    args: &[&Type],
    output: Option<&Type>,
    no_return: bool,
    attrs: &CodegenFnAttrs,
) {
    let ty = cx.type_func(args, output.unwrap_or_else(|| cx.type_void()));
    let llfn = declare_simple_fn(
        &cx,
        from_name,
        llvm::CallConv::CCallConv,
        llvm::UnnamedAddr::Global,
        llvm::Visibility::from_generic(tcx.sess.default_visibility()),
        ty,
    );

    llfn_attrs_from_instance(cx, tcx, llfn, attrs, None);

    let no_return = if no_return {
        // -> ! DIFlagNoReturn
        let no_return = llvm::AttributeKind::NoReturn.create_attr(cx.llcx);
        attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
        Some(no_return)
    } else {
        None
    };

    if tcx.sess.target.is_like_gpu {
        // Conservatively apply convergent to all functions in case they may call
        // a convergent function. Rely on LLVM to optimize away the unnecessary
        // convergent attributes.
        attributes::apply_to_llfn(
            llfn,
            llvm::AttributePlace::Function,
            &[llvm::AttributeKind::Convergent.create_attr(cx.llcx)],
        );
    }

    let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
    let mut bx = SBuilder::build(&cx, llbb);

    if let Some(to_name) = to_name {
        let callee = declare_simple_fn(
            &cx,
            to_name,
            llvm::CallConv::CCallConv,
            llvm::UnnamedAddr::Global,
            llvm::Visibility::Hidden,
            ty,
        );
        if let Some(no_return) = no_return {
            // -> ! DIFlagNoReturn
            attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
        }
        llvm::set_visibility(callee, llvm::Visibility::Hidden);

        let args = args
            .iter()
            .enumerate()
            .map(|(i, _)| llvm::get_param(llfn, i as c_uint))
            .collect::<Vec<_>>();
        let ret = bx.call(ty, callee, &args, None);
        llvm::LLVMSetTailCall(ret, TRUE);
        if output.is_some() {
            bx.ret(ret);
        } else {
            bx.ret_void()
        }
    } else {
        assert!(output.is_none());
        bx.ret_void()
    }
}
