// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

use std::collections::hash_map::HashMap;

use arc_anyhow::Result;
use itertools::Itertools;
use once_cell::sync::Lazy;

use ffi_types::{FfiU8Slice, FfiU8SliceBox};
use ir::{self, make_ir_from_parts, Func, Identifier, Item, Record, IR};

/// Generates `IR` from a header containing `header_source`.
pub fn ir_from_cc(platform: multiplatform_testing::Platform, header_source: &str) -> Result<IR> {
    ir_from_cc_dependency(platform, header_source, "// empty header")
}

/// Prepends definitions for lifetime annotation macros to the code.
pub fn with_lifetime_macros(source: &str) -> String {
    let mut result = String::from(
        r#"
    #define $(l) [[clang::annotate_type("lifetime", #l)]]
    "#,
    );
    for l in 'a'..='z' {
        result.push_str(&format!("#define ${} $({})\n", l, l));
    }
    result.push_str("#define $static $(static)\n");
    result.push_str(source);
    result
}

/// Name of the current target used by `ir_from_cc` and `ir_from_cc_dependency`.
pub const TESTING_TARGET: &str = "//test:testing_target";
static TESTING_FEATURES: Lazy<flagset::FlagSet<crubit_feature::CrubitFeature>> = Lazy::new(|| {
    crubit_feature::CrubitFeature::Experimental | crubit_feature::CrubitFeature::Supported
});

/// Update the IR to have common test-only items.
///
/// This provides one place to update the IR that affects both
/// `make_ir_from_items` and `ir_from_cc_dependency`.
fn update_test_ir(ir: &mut IR) {
    *ir.target_crubit_features_mut(&ir.current_target().clone()) = *TESTING_FEATURES;
    *ir.target_crubit_features_mut(&ir::BazelLabel(DEPENDENCY_TARGET.into())) = *TESTING_FEATURES;
}

/// Create a testing `IR` instance from given items, using mock values for other
/// fields.
pub fn make_ir_from_items(items: impl IntoIterator<Item = Item>) -> IR {
    let mut ir = make_ir_from_parts(
        items.into_iter().collect_vec(),
        /* public_headers= */ vec![],
        /* current_target= */ TESTING_TARGET.into(),
        /* top_level_item_ids= */ vec![],
        /* crate_root_path= */ None,
        /* crubit_features= */
        <HashMap<ir::BazelLabel, flagset::FlagSet<crubit_feature::CrubitFeature>>>::new(),
    );
    update_test_ir(&mut ir);
    ir
}

/// Target of the dependency used by `ir_from_cc_dependency`.
/// Needs to be kept in sync with `kDependencyTarget` in `json_from_cc.cc`.
pub const DEPENDENCY_TARGET: &str = "//test:dependency";

/// Generates `IR` from a header that depends on another header.
///
/// `header_source` of the header will be updated to contain the `#include` line
/// for the header with `dependency_header_source`. The name of the dependency
/// target is exposed as `DEPENDENCY_TARGET`.
pub fn ir_from_cc_dependency(
    platform: multiplatform_testing::Platform,
    header_source: &str,
    dependency_header_source: &str,
) -> Result<IR> {
    const DEPENDENCY_HEADER_NAME: &str = "test/dependency_header.h";

    extern "C" {
        fn json_from_cc_dependency(
            target_triple: FfiU8Slice,
            header_source: FfiU8Slice,
            dependency_header_source: FfiU8Slice,
        ) -> FfiU8SliceBox;
    }

    let header_source_with_include =
        format!("#include \"{}\"\n\n{}", DEPENDENCY_HEADER_NAME, header_source);
    let header_source_with_include_u8 = header_source_with_include.as_bytes();
    let dependency_header_source_u8 = dependency_header_source.as_bytes();
    let json_utf8 = unsafe {
        json_from_cc_dependency(
            FfiU8Slice::from_slice(platform.target_triple().as_ref()),
            FfiU8Slice::from_slice(header_source_with_include_u8),
            FfiU8Slice::from_slice(dependency_header_source_u8),
        )
        .into_boxed_slice()
    };
    let mut ir = ir::deserialize_ir(&*json_utf8)?;
    update_test_ir(&mut ir);
    Ok(ir)
}

/// Creates an identifier
pub fn ir_id(name: &str) -> Identifier {
    Identifier { identifier: name.into() }
}

/// Creates a simple `Item::Record` with a given name.
pub fn ir_record(platform: multiplatform_testing::Platform, name: &str) -> Record {
    let ir = ir_from_cc(platform, "struct REPLACEME final {};").unwrap();
    for item in ir.items() {
        if let Item::Record(record) = item {
            let mut record = (**record).clone();
            record.rs_name = name.into();
            record.cc_name = name.into();
            return record;
        }
    }
    panic!("Test IR doesn't contain a record");
}

/// Retrieves the function with the given name.
/// Panics if no such function could be found.
pub fn retrieve_func<'a>(ir: &'a IR, name: &str) -> &'a Func {
    for func in ir.functions() {
        if func.name == ir::UnqualifiedIdentifier::Identifier(ir_id(name)) {
            return func;
        }
    }
    panic!("Didn't find function with name {}", name);
}

/// Retrieves the `Record` with the given name.
/// Panics if no such record could be found.
pub fn retrieve_record<'a>(ir: &'a IR, cc_name: &str) -> &'a Record {
    for record in ir.records() {
        if record.cc_name.as_ref() == cc_name {
            return record;
        }
    }
    panic!("Didn't find record with cc_name {}", cc_name);
}

#[cfg(test)]
mod tests {
    use super::*;
    use arc_anyhow::Result;
    use googletest::prelude::*;
    use ir::ItemId;
    use ir_matchers::assert_ir_matches;
    use multiplatform_testing::Platform;
    use quote::quote;

    #[gtest]
    fn test_features_ir_from_cc() -> Result<()> {
        assert_ir_matches!(
            ir_from_cc(multiplatform_testing::Platform::X86Linux, "")?,
            quote! {
                crubit_features: hash_map!{
                    ...
                    BazelLabel("//test:testing_target"): SerializedCrubitFeatures(FlagSet(Supported|Experimental))
                    ...
                }
            }
        );
        Ok(())
    }
    #[gtest]
    fn test_features_ir_from_items() -> Result<()> {
        assert_ir_matches!(
            make_ir_from_items([]),
            quote! {
                crubit_features: hash_map!{
                    ...
                    BazelLabel("//test:testing_target"): SerializedCrubitFeatures(FlagSet(Supported|Experimental))
                    ...
                }
            }
        );
        Ok(())
    }

    #[gtest]
    #[should_panic(expected = "Duplicate decl_id found in")]
    fn test_duplicate_decl_ids_err() {
        let mut r1 = ir_record(Platform::X86Linux, "R1");
        r1.id = ItemId::new_for_testing(42);
        let mut r2 = ir_record(Platform::X86Linux, "R2");
        r2.id = ItemId::new_for_testing(42);
        let _ = make_ir_from_items([r1.into(), r2.into()]);
    }
}
