use std::{env, fs};

use gccjit::{Context, OutputKind};
use rustc_codegen_ssa::back::link::ensure_removed;
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
use rustc_fs_util::link_or_copy;
use rustc_log::tracing::debug;
use rustc_session::config::OutputType;
use rustc_target::spec::SplitDebuginfo;

use crate::base::add_pic_option;
use crate::errors::CopyBitcode;
use crate::{GccCodegenBackend, GccContext, LtoMode};

pub(crate) fn codegen(
    cgcx: &CodegenContext<GccCodegenBackend>,
    module: ModuleCodegen<GccContext>,
    config: &ModuleConfig,
) -> CompiledModule {
    let dcx = cgcx.create_dcx();
    let dcx = dcx.handle();

    let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name);
    {
        let context = &module.module_llvm.context;

        let lto_mode = module.module_llvm.lto_mode;
        let lto_supported = module.module_llvm.lto_supported;

        let bc_out = cgcx.output_filenames.temp_path_for_cgu(
            OutputType::Bitcode,
            &module.name,
            cgcx.invocation_temp.as_deref(),
        );
        let obj_out = cgcx.output_filenames.temp_path_for_cgu(
            OutputType::Object,
            &module.name,
            cgcx.invocation_temp.as_deref(),
        );

        if config.bitcode_needed() {
            let _timer = cgcx
                .prof
                .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name);

            // TODO(antoyo)
            /*if let Some(bitcode_filename) = bc_out.file_name() {
                cgcx.prof.artifact_size(
                    "llvm_bitcode",
                    bitcode_filename.to_string_lossy(),
                    data.len() as u64,
                );
            }*/

            if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
                let _timer = cgcx
                    .prof
                    .generic_activity_with_arg("GCC_module_codegen_emit_bitcode", &*module.name);
                if lto_supported {
                    context.add_command_line_option("-flto=auto");
                    context.add_command_line_option("-flto-partition=one");
                }
                context
                    .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str"));
            }

            if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) {
                let _timer = cgcx
                    .prof
                    .generic_activity_with_arg("GCC_module_codegen_embed_bitcode", &*module.name);
                if lto_supported {
                    // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes?
                    //embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data);

                    context.add_command_line_option("-flto=auto");
                    context.add_command_line_option("-flto-partition=one");
                    context.add_command_line_option("-ffat-lto-objects");
                }
                // TODO(antoyo): Send -plugin/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so to linker (this should be done when specifying the appropriate rustc cli argument).
                context
                    .compile_to_file(OutputKind::ObjectFile, bc_out.to_str().expect("path to str"));
            }
        }

        if config.emit_ir {
            let out = cgcx.output_filenames.temp_path_for_cgu(
                OutputType::LlvmAssembly,
                &module.name,
                cgcx.invocation_temp.as_deref(),
            );
            std::fs::write(out, "").expect("write file");
        }

        if config.emit_asm {
            let _timer =
                cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name);
            let path = cgcx.output_filenames.temp_path_for_cgu(
                OutputType::Assembly,
                &module.name,
                cgcx.invocation_temp.as_deref(),
            );
            context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str"));
        }

        match config.emit_obj {
            EmitObj::ObjectCode(_) => {
                let _timer = cgcx
                    .prof
                    .generic_activity_with_arg("GCC_module_codegen_emit_obj", &*module.name);
                if env::var("CG_GCCJIT_DUMP_MODULE_NAMES").as_deref() == Ok("1") {
                    println!("Module {}", module.name);
                }
                if env::var("CG_GCCJIT_DUMP_ALL_MODULES").as_deref() == Ok("1")
                    || env::var("CG_GCCJIT_DUMP_MODULE").as_deref() == Ok(&module.name)
                {
                    println!("Dumping reproducer {}", module.name);
                    let _ = fs::create_dir("/tmp/reproducers");
                    // FIXME(antoyo): segfault in dump_reproducer_to_file() might be caused by
                    // transmuting an rvalue to an lvalue.
                    // Segfault is actually in gcc::jit::reproducer::get_identifier_as_lvalue
                    context.dump_reproducer_to_file(format!("/tmp/reproducers/{}.c", module.name));
                    println!("Dumped reproducer {}", module.name);
                }
                if env::var("CG_GCCJIT_DUMP_TO_FILE").as_deref() == Ok("1") {
                    let _ = fs::create_dir("/tmp/gccjit_dumps");
                    let path = &format!("/tmp/gccjit_dumps/{}.c", module.name);
                    context.set_debug_info(true);
                    context.dump_to_file(path, true);
                }
                if lto_mode != LtoMode::None {
                    let fat_lto = lto_mode == LtoMode::Fat;
                    // We need to check if we're doing LTO since this code is also used for the
                    // dummy ThinLTO implementation to combine the object files.
                    if fat_lto {
                        context.add_command_line_option("-flto=auto");
                        context.add_command_line_option("-flto-partition=one");

                        // NOTE: without -fuse-linker-plugin, we get the following error:
                        // lto1: internal compiler error: decompressed stream: Destination buffer is too small
                        // TODO(antoyo): since we do not do LTO when the linker is invoked anymore, perhaps
                        // the following flag is not necessary anymore.
                        context.add_driver_option("-fuse-linker-plugin");
                    }

                    context.add_driver_option("-Wl,-r");
                    // NOTE: we need -nostdlib, otherwise, we get the following error:
                    // /usr/bin/ld: cannot find -lgcc_s: No such file or directory
                    context.add_driver_option("-nostdlib");

                    let path = obj_out.to_str().expect("path to str");

                    if fat_lto {
                        let lto_path = format!("{}.lto", path);
                        // cSpell:disable
                        // FIXME(antoyo): The LTO frontend generates the following warning:
                        // ../build_sysroot/sysroot_src/library/core/src/num/dec2flt/lemire.rs:150:15: warning: type of ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ does not match original declaration [-Wlto-type-mismatch]
                        // 150 |     let (lo5, hi5) = POWER_OF_FIVE_128[index];
                        //     |               ^
                        // lto1: note: ‘_ZN4core3num7dec2flt5table17POWER_OF_FIVE_12817ha449a68fb31379e4E’ was previously declared here
                        //
                        // This option is to mute it to make the UI tests pass with LTO enabled.
                        // cSpell:enable
                        context.add_driver_option("-Wno-lto-type-mismatch");
                        // NOTE: this doesn't actually generate an executable. With the above
                        // flags, it combines the .o files together in another .o.
                        context.compile_to_file(OutputKind::Executable, &lto_path);

                        let context = Context::default();
                        if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" {
                            // NOTE: it seems we need to use add_driver_option instead of
                            // add_command_line_option here because we use the LTO frontend via gcc.
                            context.add_driver_option("-masm=intel");
                        }

                        // NOTE: these two options are needed to invoke LTO to produce an object file.
                        // We need to initiate a second compilation because the arguments "-x lto"
                        // needs to be at the very beginning.
                        context.add_driver_option("-x");
                        context.add_driver_option("lto");
                        add_pic_option(&context, module.module_llvm.relocation_model);
                        context.add_driver_option(lto_path);

                        context.compile_to_file(OutputKind::ObjectFile, path);
                    } else {
                        // NOTE: this doesn't actually generate an executable. With the above
                        // flags, it combines the .o files together in another .o.
                        context.compile_to_file(OutputKind::Executable, path);
                    }
                } else {
                    context.compile_to_file(
                        OutputKind::ObjectFile,
                        obj_out.to_str().expect("path to str"),
                    );
                }
            }

            EmitObj::Bitcode => {
                debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
                if let Err(err) = link_or_copy(&bc_out, &obj_out) {
                    dcx.emit_err(CopyBitcode { err });
                }

                if !config.emit_bc {
                    debug!("removing_bitcode {:?}", bc_out);
                    ensure_removed(dcx, &bc_out);
                }
            }

            EmitObj::None => {}
        }
    }

    module.into_compiled_module(
        config.emit_obj != EmitObj::None,
        cgcx.target_can_use_split_dwarf && cgcx.split_debuginfo == SplitDebuginfo::Unpacked,
        config.emit_bc,
        config.emit_asm,
        config.emit_ir,
        &cgcx.output_filenames,
        cgcx.invocation_temp.as_deref(),
    )
}

pub(crate) fn save_temp_bitcode(
    cgcx: &CodegenContext<GccCodegenBackend>,
    _module: &ModuleCodegen<GccContext>,
    _name: &str,
) {
    if !cgcx.save_temps {
        return;
    }
    unimplemented!();
    /*unsafe {
        let ext = format!("{}.bc", name);
        let cgu = Some(&module.name[..]);
        let path = cgcx.output_filenames.temp_path_ext(&ext, cgu);
        let cstr = path_to_c_string(&path);
        let llmod = module.module_llvm.llmod();
        llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr());
    }*/
}
