use std::any::Any;
use std::hash::Hash;

use rustc_ast::expand::allocator::AllocatorMethod;
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_metadata::EncodedMetadata;
use rustc_metadata::creader::MetadataLoaderDyn;
use rustc_middle::dep_graph::WorkProductMap;
use rustc_middle::ty::TyCtxt;
use rustc_middle::util::Providers;
use rustc_session::config::{CrateType, OutputFilenames, PrintRequest};
use rustc_session::{IncrCompSession, Session};
use rustc_span::Symbol;

use super::CodegenObject;
use crate::back::archive::ArArchiveBuilderBuilder;
use crate::back::link::link_binary;
use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};

pub trait BackendTypes {
    type Function: CodegenObject;
    type BasicBlock: Copy;
    type Funclet;

    type Value: CodegenObject + PartialEq;
    type Type: CodegenObject + PartialEq;
    type FunctionSignature: CodegenObject + PartialEq;

    // FIXME(eddyb) find a common convention for all of the debuginfo-related
    // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
    type DIScope: Copy + Hash + PartialEq + Eq;
    type DILocation: Copy;
    type DIVariable: Copy;
}

pub trait CodegenBackend {
    fn name(&self) -> &'static str;

    fn init(&self, _sess: &Session) {}

    fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}

    /// Collect target-specific options that should be set in `cfg(...)`, including
    /// `target_feature` and support for unstable float types.
    fn target_config(&self, _sess: &Session) -> TargetConfig {
        TargetConfig {
            internal_target_features: Default::default(),
            // `true` is used as a default so backends need to acknowledge when they do not
            // support the float types, rather than accidentally quietly skipping all tests.
            has_reliable_f16: true,
            has_reliable_f16_math: true,
            has_reliable_f128: true,
            has_reliable_f128_math: true,
        }
    }

    fn supported_crate_types(&self, _sess: &Session) -> Vec<CrateType> {
        vec![
            CrateType::Executable,
            CrateType::Dylib,
            CrateType::Rlib,
            CrateType::StaticLib,
            CrateType::Cdylib,
            CrateType::ProcMacro,
            CrateType::Sdylib,
        ]
    }

    fn print_passes(&self) {}

    fn print_version(&self) {}

    /// Returns a list of all intrinsics that this backend definitely
    /// replaces, which means their fallback bodies do not need to be monomorphized.
    fn replaced_intrinsics(&self) -> Vec<Symbol> {
        vec![]
    }

    /// Returns a list of all intrinsics that this backend definitely
    /// does *not* replace, which means their fallback bodies can be MIR-inlined.
    fn fallback_intrinsics(&self) -> Vec<Symbol> {
        vec![]
    }

    /// Is ThinLTO supported by this backend?
    fn thin_lto_supported(&self) -> bool {
        true
    }

    /// Value printed by `--print=backend-has-zstd`.
    ///
    /// Used by compiletest to determine whether tests involving zstd compression
    /// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped.
    fn has_zstd(&self) -> bool {
        false
    }

    /// Value printed by `--print=backend-has-mnemonic:...`.
    ///
    /// Used by compiletest to determine whether tests involving `asm!()` should
    /// be executed or skipped.
    fn has_mnemonic(&self, _sess: &Session, _mnemonic: &str) -> bool {
        false
    }

    /// The metadata loader used to load rlib and dylib metadata.
    ///
    /// Alternative codegen backends may want to use different rlib or dylib formats than the
    /// default native static archives and dynamic libraries.
    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
        Box::new(crate::back::metadata::DefaultMetadataLoader)
    }

    fn provide(&self, _providers: &mut Providers) {}

    fn target_cpu(&self, sess: &Session) -> String;

    fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any>;

    /// This is called on the returned `Box<dyn Any>` from [`codegen_crate`](Self::codegen_crate)
    ///
    /// # Panics
    ///
    /// Panics when the passed `Box<dyn Any>` was not returned by [`codegen_crate`](Self::codegen_crate).
    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        sess: &Session,
        incr_comp_session: Option<&IncrCompSession>,
        outputs: &OutputFilenames,
        crate_info: &CrateInfo,
    ) -> (CompiledModules, WorkProductMap);

    fn print_pass_timings(&self) {}

    fn print_statistics(&self) {}

    fn print_statistics_json(&self) -> String {
        String::new()
    }

    /// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen).
    fn link(
        &self,
        sess: &Session,
        compiled_modules: CompiledModules,
        crate_info: CrateInfo,
        metadata: EncodedMetadata,
        outputs: &OutputFilenames,
    ) {
        link_binary(
            sess,
            &ArArchiveBuilderBuilder,
            compiled_modules,
            crate_info,
            metadata,
            outputs,
            self.name(),
        );
    }
}

pub trait ExtraBackendMethods: Send + Sync + DynSend + DynSync {
    type Module;

    fn codegen_allocator<'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        module_name: &str,
        methods: &[AllocatorMethod],
    ) -> Self::Module;

    /// This generates the codegen unit and returns it along with
    /// a `u64` giving an estimate of the unit's processing cost.
    fn compile_codegen_unit(
        &self,
        tcx: TyCtxt<'_>,
        cgu_name: Symbol,
    ) -> (ModuleCodegen<Self::Module>, u64);
}
