use std::cell::{Cell, RefCell};
use std::collections::HashMap;

use gccjit::{
    Block, CType, Context, Function, FunctionPtrType, FunctionType, LValue, Location, RValue, Type,
};
use rustc_abi::{Align, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::errors as ssa_errors;
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::interpret::Allocation;
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::{
    FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError,
    LayoutOfHelpers,
};
use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt};
use rustc_session::Session;
#[cfg(feature = "master")]
use rustc_session::config::DebugInfo;
use rustc_span::{DUMMY_SP, Span, respan};
use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, TlsModel, X86Abi};

#[cfg(feature = "master")]
use crate::abi::conv_to_fn_attribute;
use crate::callee::get_fn;
use crate::common::SignType;

#[cfg_attr(not(feature = "master"), expect(dead_code))]
pub struct CodegenCx<'gcc, 'tcx> {
    /// A cache of converted ConstAllocs
    pub const_cache: RefCell<HashMap<Allocation, RValue<'gcc>>>,
    pub codegen_unit: &'tcx CodegenUnit<'tcx>,
    pub context: &'gcc Context<'gcc>,

    // FIXME(bjorn3): Can this field be removed?
    pub current_func: RefCell<Option<Function<'gcc>>>,
    pub normal_function_addresses: RefCell<FxHashSet<RValue<'gcc>>>,
    pub function_address_names: RefCell<FxHashMap<RValue<'gcc>, String>>,

    pub functions: RefCell<FxHashMap<String, Function<'gcc>>>,
    pub intrinsics: RefCell<FxHashMap<String, Function<'gcc>>>,

    pub tls_model: gccjit::TlsModel,

    pub bool_type: Type<'gcc>,
    pub i8_type: Type<'gcc>,
    pub i16_type: Type<'gcc>,
    pub i32_type: Type<'gcc>,
    pub i64_type: Type<'gcc>,
    pub i128_type: Type<'gcc>,
    pub isize_type: Type<'gcc>,

    pub u8_type: Type<'gcc>,
    pub u16_type: Type<'gcc>,
    pub u32_type: Type<'gcc>,
    pub u64_type: Type<'gcc>,
    pub u128_type: Type<'gcc>,
    pub usize_type: Type<'gcc>,

    pub char_type: Type<'gcc>,
    pub uchar_type: Type<'gcc>,
    pub short_type: Type<'gcc>,
    pub ushort_type: Type<'gcc>,
    pub int_type: Type<'gcc>,
    pub uint_type: Type<'gcc>,
    pub long_type: Type<'gcc>,
    pub ulong_type: Type<'gcc>,
    pub longlong_type: Type<'gcc>,
    pub ulonglong_type: Type<'gcc>,
    pub sizet_type: Type<'gcc>,

    pub supports_128bit_integers: bool,
    pub supports_f16_type: bool,
    pub supports_f32_type: bool,
    pub supports_f64_type: bool,
    pub supports_f128_type: bool,

    pub float_type: Type<'gcc>,
    pub double_type: Type<'gcc>,

    pub linkage: Cell<FunctionType>,
    pub scalar_types: RefCell<FxHashMap<Ty<'tcx>, Type<'gcc>>>,
    pub types: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), Type<'gcc>>>,
    pub tcx: TyCtxt<'tcx>,

    pub struct_types: RefCell<FxHashMap<Vec<Type<'gcc>>, Type<'gcc>>>,

    /// Cache instances of monomorphic and polymorphic items
    pub instances: RefCell<FxHashMap<Instance<'tcx>, LValue<'gcc>>>,
    /// Cache function instances of monomorphic and polymorphic items
    pub function_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
    /// Cache function instances of intrinsics
    pub intrinsic_instances: RefCell<FxHashMap<Instance<'tcx>, Function<'gcc>>>,
    /// Cache generated vtables
    pub vtables:
        RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), RValue<'gcc>>>,

    // FIXME(antoyo): improve the SSA API to not require those.
    /// Mapping from function pointer type to indexes of on stack parameters.
    pub on_stack_params: RefCell<FxHashMap<FunctionPtrType<'gcc>, FxHashSet<usize>>>,
    /// Mapping from function to indexes of on stack parameters.
    pub on_stack_function_params: RefCell<FxHashMap<Function<'gcc>, FxHashSet<usize>>>,

    /// Cache of emitted const globals (value -> global)
    pub const_globals: RefCell<FxHashMap<RValue<'gcc>, RValue<'gcc>>>,

    /// Map from the address of a global variable (rvalue) to the global variable itself (lvalue).
    /// FIXME(antoyo): remove when the rustc API is fixed.
    pub global_lvalues: RefCell<FxHashMap<RValue<'gcc>, LValue<'gcc>>>,

    /// Cache of constant strings,
    pub const_str_cache: RefCell<FxHashMap<String, LValue<'gcc>>>,

    /// Cache of globals.
    pub globals: RefCell<FxHashMap<String, RValue<'gcc>>>,

    /// A counter that is used for generating local symbol names
    local_gen_sym_counter: Cell<usize>,

    eh_personality: Cell<Option<Function<'gcc>>>,
    #[cfg(feature = "master")]
    pub rust_try_fn: Cell<Option<(Type<'gcc>, Function<'gcc>)>>,

    pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,

    #[cfg(feature = "master")]
    pub cleanup_blocks: RefCell<FxHashSet<Block<'gcc>>>,
    /// The alignment of a u128/i128 type.
    // We cache this, since it is needed for alignment checks during loads.
    pub int128_align: Align,
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
    #[expect(clippy::too_many_arguments)]
    pub fn new(
        context: &'gcc Context<'gcc>,
        codegen_unit: &'tcx CodegenUnit<'tcx>,
        tcx: TyCtxt<'tcx>,
        supports_128bit_integers: bool,
        supports_f16_type: bool,
        supports_f32_type: bool,
        supports_f64_type: bool,
        supports_f128_type: bool,
    ) -> Self {
        #[cfg(feature = "master")]
        if tcx.sess.opts.debuginfo != DebugInfo::None {
            context.set_filename(codegen_unit.name().as_str());
        }

        let create_type = |ctype, rust_type| {
            let layout = tcx
                .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
                .unwrap();
            let align = layout.align.bytes();
            // For types with size 1, the alignment can be 1 and only 1
            // So, we can skip the call to ``get_aligned`.
            // In the future, we can add a GCC API to query the type align,
            // and call `get_aligned` if and only if that differs from Rust's expectations.
            if layout.size.bytes() == 1 {
                return context.new_c_type(ctype);
            }
            #[cfg(feature = "master")]
            {
                context.new_c_type(ctype).get_aligned(align)
            }
            #[cfg(not(feature = "master"))]
            {
                // Since libgccjit 12 doesn't contain the fix to compare aligned integer types,
                // only align u128 and i128.
                if layout.ty.int_size_and_signed(tcx).0.bytes() == 16 {
                    context.new_c_type(ctype).get_aligned(align)
                } else {
                    context.new_c_type(ctype)
                }
            }
        };

        let i8_type = create_type(CType::Int8t, tcx.types.i8);
        let i16_type = create_type(CType::Int16t, tcx.types.i16);
        let i32_type = create_type(CType::Int32t, tcx.types.i32);
        let i64_type = create_type(CType::Int64t, tcx.types.i64);
        let u8_type = create_type(CType::UInt8t, tcx.types.u8);
        let u16_type = create_type(CType::UInt16t, tcx.types.u16);
        let u32_type = create_type(CType::UInt32t, tcx.types.u32);
        let u64_type = create_type(CType::UInt64t, tcx.types.u64);

        let (i128_type, u128_type) = if supports_128bit_integers {
            let i128_type = create_type(CType::Int128t, tcx.types.i128);
            let u128_type = create_type(CType::UInt128t, tcx.types.u128);
            (i128_type, u128_type)
        } else {
            /*let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.i128)).unwrap();
            let i128_align = layout.align.bytes();
            let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.u128)).unwrap();
            let u128_align = layout.align.bytes();*/

            // FIXME(antoyo): re-enable the alignment when libgccjit fixed the issue in
            // gcc_jit_context_new_array_constructor (it should not use reinterpret_cast).
            let i128_type = new_array_type(context, None, i64_type, 2)/*.get_aligned(i128_align)*/;
            let u128_type = new_array_type(context, None, u64_type, 2)/*.get_aligned(u128_align)*/;
            (i128_type, u128_type)
        };

        let tls_model = to_gcc_tls_mode(tcx.sess.tls_model());

        // FIXME(antoyo): set alignment on those types as well.
        let float_type = context.new_type::<f32>();
        let double_type = context.new_type::<f64>();

        let char_type = context.new_c_type(CType::Char);
        let uchar_type = context.new_c_type(CType::UChar);
        let short_type = context.new_c_type(CType::Short);
        let ushort_type = context.new_c_type(CType::UShort);
        let int_type = context.new_c_type(CType::Int);
        let uint_type = context.new_c_type(CType::UInt);
        let long_type = context.new_c_type(CType::Long);
        let ulong_type = context.new_c_type(CType::ULong);
        let longlong_type = context.new_c_type(CType::LongLong);
        let ulonglong_type = context.new_c_type(CType::ULongLong);
        let sizet_type = context.new_c_type(CType::SizeT);

        let usize_type = sizet_type;
        let isize_type = usize_type;
        let bool_type = context.new_type::<bool>();

        let mut functions = FxHashMap::default();
        let builtins = ["abort"];

        for builtin in builtins.iter() {
            functions.insert(builtin.to_string(), context.get_builtin_function(builtin));
        }

        let mut cx = Self {
            int128_align: tcx
                .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(tcx.types.i128))
                .expect("Can't get the layout of `i128`")
                .align
                .abi,
            const_cache: Default::default(),
            codegen_unit,
            context,
            current_func: RefCell::new(None),
            normal_function_addresses: Default::default(),
            function_address_names: Default::default(),
            functions: RefCell::new(functions),
            intrinsics: RefCell::new(FxHashMap::default()),

            tls_model,

            bool_type,
            i8_type,
            i16_type,
            i32_type,
            i64_type,
            i128_type,
            isize_type,
            usize_type,
            u8_type,
            u16_type,
            u32_type,
            u64_type,
            u128_type,
            char_type,
            uchar_type,
            short_type,
            ushort_type,
            int_type,
            uint_type,
            long_type,
            ulong_type,
            longlong_type,
            ulonglong_type,
            sizet_type,

            supports_128bit_integers,
            supports_f16_type,
            supports_f32_type,
            supports_f64_type,
            supports_f128_type,

            float_type,
            double_type,

            linkage: Cell::new(FunctionType::Internal),
            instances: Default::default(),
            function_instances: Default::default(),
            intrinsic_instances: Default::default(),
            on_stack_params: Default::default(),
            on_stack_function_params: Default::default(),
            vtables: Default::default(),
            const_globals: Default::default(),
            global_lvalues: Default::default(),
            const_str_cache: Default::default(),
            globals: Default::default(),
            scalar_types: Default::default(),
            types: Default::default(),
            tcx,
            struct_types: Default::default(),
            local_gen_sym_counter: Cell::new(0),
            eh_personality: Cell::new(None),
            #[cfg(feature = "master")]
            rust_try_fn: Cell::new(None),
            pointee_infos: Default::default(),
            #[cfg(feature = "master")]
            cleanup_blocks: Default::default(),
        };
        // FIXME(antoyo): instead of doing this, add SsizeT to libgccjit.
        cx.isize_type = usize_type.to_signed(&cx);
        cx
    }

    pub fn rvalue_as_function(&self, value: RValue<'gcc>) -> Function<'gcc> {
        let function: Function<'gcc> = unsafe { std::mem::transmute(value) };
        debug_assert!(
            self.functions.borrow().values().any(|value| *value == function),
            "{:?} ({:?}) is not a function",
            value,
            value.get_type()
        );
        function
    }

    pub fn is_native_int_type(&self, typ: Type<'gcc>) -> bool {
        let types = [
            self.u8_type,
            self.u16_type,
            self.u32_type,
            self.u64_type,
            self.i8_type,
            self.i16_type,
            self.i32_type,
            self.i64_type,
        ];

        for native_type in types {
            if native_type.is_compatible_with(typ) {
                return true;
            }
        }

        self.supports_128bit_integers
            && (self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ))
    }

    pub fn is_non_native_int_type(&self, typ: Type<'gcc>) -> bool {
        !self.supports_128bit_integers
            && (self.u128_type.is_compatible_with(typ) || self.i128_type.is_compatible_with(typ))
    }

    pub fn is_native_int_type_or_bool(&self, typ: Type<'gcc>) -> bool {
        self.is_native_int_type(typ) || typ.is_compatible_with(self.bool_type)
    }

    pub fn is_int_type_or_bool(&self, typ: Type<'gcc>) -> bool {
        self.is_native_int_type(typ)
            || self.is_non_native_int_type(typ)
            || typ.is_compatible_with(self.bool_type)
    }

    pub fn sess(&self) -> &'tcx Session {
        self.tcx.sess
    }

    pub fn bitcast_if_needed(
        &self,
        value: RValue<'gcc>,
        expected_type: Type<'gcc>,
    ) -> RValue<'gcc> {
        if value.get_type() != expected_type {
            self.context.new_bitcast(None, value, expected_type)
        } else {
            value
        }
    }
}

impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
    type Function = Function<'gcc>;
    type BasicBlock = Block<'gcc>;
    type Funclet = (); // FIXME(antoyo)

    type Value = RValue<'gcc>;
    type Type = Type<'gcc>;
    type FunctionSignature = Type<'gcc>;

    type DIScope = (); // FIXME(antoyo)
    type DILocation = Location<'gcc>;
    type DIVariable = (); // FIXME(antoyo)
}

impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
    fn vtables(
        &self,
    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
        &self.vtables
    }

    fn get_fn(&self, instance: Instance<'tcx>) -> Function<'gcc> {
        get_fn(self, instance)
    }

    fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> {
        let func_name = self.tcx.symbol_name(instance).name;

        let func = if let Some(variable) = self.get_declared_value(func_name) {
            return variable;
        } else {
            get_fn(self, instance)
        };
        let ptr = func.get_address(None);

        // FIXME(antoyo): don't do this twice: i.e. in declare_fn and here.
        // FIXME(antoyo): the rustc API seems to call get_fn_addr() when not needed (e.g. for FFI).

        self.normal_function_addresses.borrow_mut().insert(ptr);
        self.function_address_names.borrow_mut().insert(ptr, func_name.to_string());

        ptr
    }

    fn eh_personality(&self) -> Function<'gcc> {
        // The exception handling personality function.
        //
        // If our compilation unit has the `eh_personality` lang item somewhere
        // within it, then we just need to codegen that. Otherwise, we're
        // building an rlib which will depend on some upstream implementation of
        // this function, so we just codegen a generic reference to it. We don't
        // specify any of the types for the function, we just make it a symbol
        // that LLVM can later use.
        //
        // Note that MSVC is a little special here in that we don't use the
        // `eh_personality` lang item at all. Currently LLVM has support for
        // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
        // *name of the personality function* to decide what kind of unwind side
        // tables/landing pads to emit. It looks like Dwarf is used by default,
        // injecting a dependency on the `_Unwind_Resume` symbol for resuming
        // an "exception", but for MSVC we want to force SEH. This means that we
        // can't actually have the personality function be our standard
        // `rust_eh_personality` function, but rather we wired it up to the
        // CRT's custom personality function, which forces LLVM to consider
        // landing pads as "landing pads for SEH".
        if let Some(personality_func) = self.eh_personality.get() {
            return personality_func;
        }
        let tcx = self.tcx;
        let func = match tcx.lang_items().eh_personality() {
            Some(def_id) if !wants_msvc_seh(self.sess()) => {
                let instance = ty::Instance::expect_resolve(
                    tcx,
                    self.typing_env(),
                    def_id,
                    ty::List::empty(),
                    DUMMY_SP,
                );

                let symbol_name = tcx.symbol_name(instance).name;
                let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
                self.linkage.set(FunctionType::Extern);
                self.declare_fn(symbol_name, fn_abi)
            }
            _ => {
                let name = if wants_msvc_seh(self.sess()) {
                    "__CxxFrameHandler3"
                } else {
                    "rust_eh_personality"
                };
                self.declare_func(name, self.type_i32(), &[], true)
            }
        };
        // FIXME(antoyo): apply target cpu attributes.
        self.eh_personality.set(Some(func));
        func
    }

    fn sess(&self) -> &Session {
        self.tcx.sess
    }

    fn set_frame_pointer_type(&self, _llfn: Function<'gcc>) {
        // FIXME(antoyo)
    }

    fn apply_target_cpu_attr(&self, _llfn: Function<'gcc>) {
        // FIXME(antoyo)
    }

    fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
        let entry_name = self.sess().target.entry_name.as_ref();
        if !self.functions.borrow().contains_key(entry_name) {
            #[cfg(feature = "master")]
            let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch);
            #[cfg(not(feature = "master"))]
            let conv = None;
            Some(self.declare_entry_fn(entry_name, fn_type, conv))
        } else {
            // If the symbol already exists, it is an error: for example, the user wrote
            // #[no_mangle] extern "C" fn main(..) {..}
            None
        }
    }
}

impl<'gcc, 'tcx> HasTyCtxt<'tcx> for CodegenCx<'gcc, 'tcx> {
    fn tcx(&self) -> TyCtxt<'tcx> {
        self.tcx
    }
}

impl<'gcc, 'tcx> HasDataLayout for CodegenCx<'gcc, 'tcx> {
    fn data_layout(&self) -> &TargetDataLayout {
        &self.tcx.data_layout
    }
}

impl<'gcc, 'tcx> HasTargetSpec for CodegenCx<'gcc, 'tcx> {
    fn target_spec(&self) -> &Target {
        &self.tcx.sess.target
    }
}

impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> {
    fn x86_abi_opt(&self) -> X86Abi {
        X86Abi {
            regparm: self.tcx.sess.opts.unstable_opts.regparm,
            reg_struct_return: self.tcx.sess.opts.unstable_opts.reg_struct_return,
        }
    }
}

impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
    #[inline]
    fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
        if let LayoutError::SizeOverflow(_)
        | LayoutError::InvalidSimd { .. }
        | LayoutError::ReferencesError(_) = err
        {
            self.tcx.dcx().span_fatal(span, err.to_string())
        } else {
            self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
        }
    }
}

impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
    #[inline]
    fn handle_fn_abi_err(
        &self,
        err: FnAbiError<'tcx>,
        span: Span,
        fn_abi_request: FnAbiRequest<'tcx>,
    ) -> ! {
        if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) =
            err
        {
            self.tcx.dcx().emit_fatal(respan(span, err))
        } else {
            match fn_abi_request {
                FnAbiRequest::OfFnPtr { sig, extra_args } => {
                    span_bug!(span, "`fn_abi_of_fn_ptr({sig}, {extra_args:?})` failed: {err:?}");
                }
                FnAbiRequest::OfInstance { instance, extra_args } => {
                    span_bug!(
                        span,
                        "`fn_abi_of_instance({instance}, {extra_args:?})` failed: {err:?}"
                    );
                }
            }
        }
    }
}

impl<'tcx, 'gcc> HasTypingEnv<'tcx> for CodegenCx<'gcc, 'tcx> {
    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
        ty::TypingEnv::fully_monomorphized()
    }
}

impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
    /// Generates a new symbol name with the given prefix. This symbol name must
    /// only be used for definitions with `internal` or `private` linkage.
    pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
        let idx = self.local_gen_sym_counter.get();
        self.local_gen_sym_counter.set(idx + 1);
        // Include a '.' character, so there can be no accidental conflicts with
        // user defined names
        let mut name = String::with_capacity(prefix.len() + 6);
        name.push_str(prefix);
        name.push('.');
        // Offset the index by the base so that always at least two characters
        // are generated. This avoids cases where the suffix is interpreted as
        // size by the assembler (for m68k: .b, .w, .l).
        name.push_str(&(idx as u64 + ALPHANUMERIC_ONLY as u64).to_base(ALPHANUMERIC_ONLY));
        name
    }
}

fn to_gcc_tls_mode(tls_model: TlsModel) -> gccjit::TlsModel {
    match tls_model {
        TlsModel::GeneralDynamic => gccjit::TlsModel::GlobalDynamic,
        TlsModel::LocalDynamic => gccjit::TlsModel::LocalDynamic,
        TlsModel::InitialExec => gccjit::TlsModel::InitialExec,
        TlsModel::LocalExec => gccjit::TlsModel::LocalExec,
        TlsModel::Emulated => gccjit::TlsModel::GlobalDynamic,
    }
}

pub fn new_array_type<'gcc>(
    context: &'gcc Context<'gcc>,
    location: Option<Location<'gcc>>,
    typ: Type<'gcc>,
    size: u64,
) -> Type<'gcc> {
    #[cfg(feature = "master")]
    {
        context.new_array_type_u64(location, typ, size)
    }
    #[cfg(not(feature = "master"))]
    context.new_array_type(location, typ, size)
}
