#[cfg(feature = "master")]
use gccjit::{FnAttribute, VarAttribute, Visibility};
use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
use rustc_abi::{self as abi, Align, HasDataLayout, Primitive, Size, WrappingRange};
use rustc_codegen_ssa::traits::{
    BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
};
use rustc_hir::attrs::Linkage;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{
    self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint,
};
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::{self, Instance};
use rustc_middle::{bug, span_bug};
use rustc_span::def_id::DefId;

use crate::base;
use crate::context::CodegenCx;
use crate::type_of::LayoutGccExt;

fn set_global_alignment<'gcc, 'tcx>(
    cx: &CodegenCx<'gcc, 'tcx>,
    gv: LValue<'gcc>,
    mut align: Align,
) {
    // The target may require greater alignment for globals than the type does.
    // Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
    // which can force it to be smaller. Rust doesn't support this yet.
    if let Some(min_global) = cx.sess().target.min_global_align {
        align = Ord::max(align, min_global);
    }
    gv.set_alignment(align.bytes() as i32);
}

impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
    fn static_addr_of(&self, cv: RValue<'gcc>, align: Align, kind: Option<&str>) -> RValue<'gcc> {
        if let Some(variable) = self.const_globals.borrow().get(&cv) {
            if let Some(global_variable) = self.global_lvalues.borrow().get(variable) {
                let alignment = align.bits() as i32;
                if alignment > global_variable.get_alignment() {
                    global_variable.set_alignment(alignment);
                }
            }
            return *variable;
        }
        let global_value = self.static_addr_of_mut(cv, align, kind);
        #[cfg(feature = "master")]
        self.global_lvalues
            .borrow()
            .get(&global_value)
            .expect("`static_addr_of_mut` did not add the global to `self.global_lvalues`")
            .global_set_readonly();
        self.const_globals.borrow_mut().insert(cv, global_value);
        global_value
    }

    #[cfg_attr(not(feature = "master"), allow(unused_mut))]
    fn codegen_static(&mut self, def_id: DefId) {
        let attrs = self.tcx.codegen_fn_attrs(def_id);

        let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else {
            // Error has already been reported
            return;
        };
        let alloc = alloc.inner();

        // boolean SSA values are i1, but they have to be stored in i8 slots,
        // otherwise some LLVM optimization passes don't work as expected
        let val_llty = self.val_ty(value);
        if val_llty == self.type_i1() {
            unimplemented!();
        };

        let is_thread_local = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
        let global = self.get_static_inner(def_id, val_llty);

        #[cfg(feature = "master")]
        if global.to_rvalue().get_type() != val_llty {
            global.to_rvalue().set_type(val_llty);
        }

        // NOTE: Alignment from attributes has already been applied to the allocation.
        set_global_alignment(self, global, alloc.align);

        global.global_set_initializer_rvalue(value);

        // As an optimization, all shared statics which do not have interior
        // mutability are placed into read-only memory.
        if alloc.mutability.is_not() {
            #[cfg(feature = "master")]
            global.global_set_readonly();
        }

        if is_thread_local {
            // Do not allow LLVM to change the alignment of a TLS on macOS.
            //
            // By default a global's alignment can be freely increased.
            // This allows LLVM to generate more performant instructions
            // e.g., using load-aligned into a SIMD register.
            //
            // However, on macOS 10.10 or below, the dynamic linker does not
            // respect any alignment given on the TLS (radar 24221680).
            // This will violate the alignment assumption, and causing segfault at runtime.
            //
            // This bug is very easy to trigger. In `println!` and `panic!`,
            // the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS,
            // which the values would be `mem::replace`d on initialization.
            // The implementation of `mem::replace` will use SIMD
            // whenever the size is 32 bytes or higher. LLVM notices SIMD is used
            // and tries to align `LOCAL_STDOUT`/`LOCAL_STDERR` to a 32-byte boundary,
            // which macOS's dyld disregarded and causing crashes
            // (see issues #51794, #51758, #50867, #48866 and #44056).
            //
            // To workaround the bug, we trick LLVM into not increasing
            // the global's alignment by explicitly assigning a section to it
            // (equivalent to automatically generating a `#[link_section]` attribute).
            // See the comment in the `GlobalValue::canIncreaseAlignment()` function
            // of `lib/IR/Globals.cpp` for why this works.
            //
            // When the alignment is not increased, the optimized `mem::replace`
            // will use load-unaligned instructions instead, and thus avoiding the crash.
            //
            // We could remove this hack whenever we decide to drop macOS 10.10 support.
            if self.tcx.sess.target.options.is_like_darwin {
                // The `inspect` method is okay here because we checked for provenance, and
                // because we are doing this access to inspect the final interpreter state
                // (not as part of the interpreter execution).
                //
                // FIXME: This check requires that the (arbitrary) value of undefined bytes
                // happens to be zero. Instead, we should only check the value of defined bytes
                // and set all undefined bytes to zero if this allocation is headed for the
                // BSS.
                unimplemented!();
            }
        }

        // Wasm statics with custom link sections get special treatment as they
        // go into custom sections of the wasm executable.
        if self.tcx.sess.target.is_like_wasm {
            if let Some(_section) = attrs.link_section {
                unimplemented!();
            }
        } else {
            // TODO(antoyo): set link section.
        }

        if attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER)
            || attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
        {
            self.add_used_global(global.to_rvalue());
        }
    }
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
    /// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*.
    pub fn add_used_global(&mut self, _global: RValue<'gcc>) {
        // TODO(antoyo)
    }

    #[cfg_attr(not(feature = "master"), allow(unused_variables))]
    pub fn add_used_function(&self, function: Function<'gcc>) {
        #[cfg(feature = "master")]
        function.add_attribute(FnAttribute::Used);
    }

    pub fn static_addr_of_mut(
        &self,
        cv: RValue<'gcc>,
        align: Align,
        kind: Option<&str>,
    ) -> RValue<'gcc> {
        let global = match kind {
            Some(kind) if !self.tcx.sess.fewer_names() => {
                let name = self.generate_local_symbol_name(kind);
                // TODO(antoyo): check if it's okay that no link_section is set.

                let typ = self.val_ty(cv).get_aligned(align.bytes());
                self.declare_private_global(&name[..], typ)
            }
            _ => {
                let typ = self.val_ty(cv).get_aligned(align.bytes());
                self.declare_unnamed_global(typ)
            }
        };
        global.global_set_initializer_rvalue(cv);
        // TODO(antoyo): set unnamed address.
        let rvalue = global.get_address(None);
        self.global_lvalues.borrow_mut().insert(rvalue, global);
        rvalue
    }

    pub fn get_static(&self, def_id: DefId) -> LValue<'gcc> {
        let instance = Instance::mono(self.tcx, def_id);
        let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
        // Nested statics do not have a type, so pick a random type and let `define_static` figure out
        // the gcc type from the actual evaluated initializer.
        let gcc_type = if nested {
            self.type_i8()
        } else {
            let ty = instance.ty(self.tcx, ty::TypingEnv::fully_monomorphized());
            self.layout_of(ty).gcc_type(self)
        };

        self.get_static_inner(def_id, gcc_type)
    }

    pub(crate) fn get_static_inner(&self, def_id: DefId, gcc_type: Type<'gcc>) -> LValue<'gcc> {
        let instance = Instance::mono(self.tcx, def_id);
        if let Some(&global) = self.instances.borrow().get(&instance) {
            trace!("used cached value");
            return global;
        }

        // FIXME: Once we stop removing globals in `codegen_static`, we can uncomment this code.
        // let defined_in_current_codegen_unit =
        //     self.codegen_unit.items().contains_key(&MonoItem::Static(def_id));
        // assert!(
        //     !defined_in_current_codegen_unit,
        //     "consts::get_static() should always hit the cache for \
        //          statics defined in the same CGU, but did not for `{:?}`",
        //     def_id
        // );
        let sym = self.tcx.symbol_name(instance).name;
        let fn_attrs = self.tcx.codegen_fn_attrs(def_id);

        let global = if def_id.is_local() && !self.tcx.is_foreign_item(def_id) {
            if let Some(global) = self.get_declared_value(sym)
                && self.val_ty(global) != self.type_ptr_to(gcc_type)
            {
                span_bug!(self.tcx.def_span(def_id), "Conflicting types for static");
            }

            let is_tls = fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
            let global = self.declare_global(
                sym,
                gcc_type,
                GlobalKind::Imported,
                is_tls,
                fn_attrs.link_section,
            );

            if !self.tcx.is_reachable_non_generic(def_id) {
                #[cfg(feature = "master")]
                global.add_attribute(VarAttribute::Visibility(Visibility::Hidden));
            }

            global
        } else {
            check_and_apply_linkage(self, fn_attrs, gcc_type, sym)
        };

        if !def_id.is_local() {
            let needs_dll_storage_attr = false; // TODO(antoyo)

            // If this assertion triggers, there's something wrong with commandline
            // argument validation.
            debug_assert!(
                !(self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
                    && self.tcx.sess.target.options.is_like_msvc
                    && self.tcx.sess.opts.cg.prefer_dynamic)
            );

            if needs_dll_storage_attr {
                // This item is external but not foreign, i.e., it originates from an external Rust
                // crate. Since we don't know whether this crate will be linked dynamically or
                // statically in the final application, we always mark such symbols as 'dllimport'.
                // If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs
                // to make things work.
                //
                // However, in some scenarios we defer emission of statics to downstream
                // crates, so there are cases where a static with an upstream DefId
                // is actually present in the current crate. We can find out via the
                // is_codegened_item query.
                if !self.tcx.is_codegened_item(def_id) {
                    unimplemented!();
                }
            }
        }

        // TODO(antoyo): set dll storage class.

        self.instances.borrow_mut().insert(instance, global);
        global
    }
}
/// Converts a given const alloc to a gcc Rvalue, without any caching or deduplication.
/// YOU SHOULD NOT call this function directly - that may break the semantics of Rust.
/// Use `const_data_from_alloc` instead.
pub(crate) fn const_alloc_to_gcc_uncached<'gcc>(
    cx: &CodegenCx<'gcc, '_>,
    alloc: ConstAllocation<'_>,
) -> RValue<'gcc> {
    let alloc = alloc.inner();
    let mut llvals = Vec::with_capacity(alloc.provenance().ptrs().len() + 1);
    let dl = cx.data_layout();
    let pointer_size = dl.pointer_size().bytes() as usize;

    let mut next_offset = 0;
    for &(offset, prov) in alloc.provenance().ptrs().iter() {
        let alloc_id = prov.alloc_id();
        let offset = offset.bytes();
        assert_eq!(offset as usize as u64, offset);
        let offset = offset as usize;
        if offset > next_offset {
            // This `inspect` is okay since we have checked that it is not within a pointer with provenance, it
            // is within the bounds of the allocation, and it doesn't affect interpreter execution
            // (we inspect the result after interpreter execution). Any undef byte is replaced with
            // some arbitrary byte value.
            //
            // FIXME: relay undef bytes to codegen as undef const bytes
            let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(next_offset..offset);
            llvals.push(cx.const_bytes(bytes));
        }
        let ptr_offset = read_target_uint(
            dl.endian,
            // This `inspect` is okay since it is within the bounds of the allocation, it doesn't
            // affect interpreter execution (we inspect the result after interpreter execution),
            // and we properly interpret the provenance as a relocation pointer offset.
            alloc.inspect_with_uninit_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
        )
        .expect("const_alloc_to_gcc_uncached: could not read relocation pointer")
            as u64;

        let address_space = cx.tcx.global_alloc(alloc_id).address_space(cx);

        llvals.push(cx.scalar_to_backend(
            InterpScalar::from_pointer(
                interpret::Pointer::new(prov, Size::from_bytes(ptr_offset)),
                &cx.tcx,
            ),
            abi::Scalar::Initialized {
                value: Primitive::Pointer(address_space),
                valid_range: WrappingRange::full(dl.pointer_size()),
            },
            cx.type_i8p_ext(address_space),
        ));
        next_offset = offset + pointer_size;
    }
    if alloc.len() >= next_offset {
        let range = next_offset..alloc.len();
        // This `inspect` is okay since we have check that it is after all provenance, it is
        // within the bounds of the allocation, and it doesn't affect interpreter execution (we
        // inspect the result after interpreter execution). Any undef byte is replaced with some
        // arbitrary byte value.
        //
        // FIXME: relay undef bytes to codegen as undef const bytes
        let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(range);
        llvals.push(cx.const_bytes(bytes));
    }

    // FIXME(bjorn3) avoid wrapping in a struct when there is only a single element.
    cx.const_struct(&llvals, true)
}

fn codegen_static_initializer<'gcc, 'tcx>(
    cx: &CodegenCx<'gcc, 'tcx>,
    def_id: DefId,
) -> Result<(RValue<'gcc>, ConstAllocation<'tcx>), ErrorHandled> {
    let alloc = cx.tcx.eval_static_initializer(def_id)?;
    Ok((cx.const_data_from_alloc(alloc), alloc))
}

fn check_and_apply_linkage<'gcc, 'tcx>(
    cx: &CodegenCx<'gcc, 'tcx>,
    attrs: &CodegenFnAttrs,
    gcc_type: Type<'gcc>,
    sym: &str,
) -> LValue<'gcc> {
    let is_tls = attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL);
    if let Some(linkage) = attrs.import_linkage {
        // Declare a symbol `foo` with the desired linkage.
        let global1 =
            cx.declare_global_with_linkage(sym, cx.type_i8(), base::global_linkage_to_gcc(linkage));

        if linkage == Linkage::ExternalWeak {
            #[cfg(feature = "master")]
            global1.add_attribute(VarAttribute::Weak);
        }

        // Declare an internal global `extern_with_linkage_foo` which
        // is initialized with the address of `foo`.  If `foo` is
        // discarded during linking (for example, if `foo` has weak
        // linkage and there are no definitions), then
        // `extern_with_linkage_foo` will instead be initialized to
        // zero.
        let real_name =
            format!("_rust_extern_with_linkage_{:016x}_{sym}", cx.tcx.stable_crate_id(LOCAL_CRATE));
        let global2 = cx.define_global(&real_name, gcc_type, is_tls, attrs.link_section);
        // TODO(antoyo): set linkage.
        let value = cx.const_ptrcast(global1.get_address(None), gcc_type);
        global2.global_set_initializer_rvalue(value);
        global2
    } else {
        // Generate an external declaration.
        // FIXME(nagisa): investigate whether it can be changed into define_global

        // Thread-local statics in some other crate need to *always* be linked
        // against in a thread-local fashion, so we need to be sure to apply the
        // thread-local attribute locally if it was present remotely. If we
        // don't do this then linker errors can be generated where the linker
        // complains that one object files has a thread local version of the
        // symbol and another one doesn't.
        cx.declare_global(sym, gcc_type, GlobalKind::Imported, is_tls, attrs.link_section)
    }
}
