// 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

/// Like `token_stream_matchers::assert_cc_matches!`, but expects `IR` instance
/// as input. The macro converts the instance to its corresponding struct
/// expression and matches the pattern against that.  See the documentation of
/// `token_stream_matchers` for more information.
///
/// Example:
/// ```rust
///    let ir = ir_from_cc(..., "struct SomeStruct {};').unwrap();
///    assert_ir_matches!(
///        ir,
///        quote! {
///            Record {
///                rs_name: "SomeStruct" ...
///            }
///        }
///    );
/// ```
#[macro_export]
macro_rules! assert_ir_matches {
    ($ir:expr, $pattern:expr $(,)*) => {
        $crate::internal::assert_ir_matches_fn(&$ir, &$pattern)
    };
}

/// Like `assert_ir_matches`, but asserts that the pattern does not match the
/// `IR`.
#[macro_export]
macro_rules! assert_ir_not_matches {
    ($ir:expr, $pattern:expr $(,)*) => {
        $crate::internal::assert_ir_not_matches_fn(&$ir, &$pattern)
    };
}

/// Like `assert_ir_matches!`, but expects a list of Items and a list of
/// TokenStreams as input. The macro converts each Item to its struct expression
/// and matches the corresponding pattern against that.
/// The use case for this macro is to compare a list of Items to expected
/// patterns, e.g when we want to confirm that the children items of an item
/// appear in a certain order.
#[macro_export]
macro_rules! assert_items_match {
    ($items:expr, $patterns:expr $(,)*) => {
        $crate::internal::assert_items_match_fn(&*$items, &*$patterns)
    };
}

/// Only used to make stuff needed by exported macros available
pub mod internal {

    use anyhow::Result;
    use ir::{Item, IR};
    use itertools::Itertools;
    pub use proc_macro2::TokenStream;
    use quote::quote;
    pub use token_stream_printer::{
        rs_tokens_to_formatted_string, rs_tokens_to_formatted_string_for_tests,
    };

    #[track_caller]
    pub fn assert_ir_matches_fn(ir: &IR, pattern: &TokenStream) {
        token_stream_matchers::internal::match_tokens(
            &ir_to_token_stream(ir).expect("Failed to convert IR to token stream"),
            pattern,
            ir_to_string,
        )
        .expect("input unexpectedly didn't match the pattern");
    }

    #[track_caller]
    pub fn assert_ir_not_matches_fn(ir: &IR, pattern: &TokenStream) {
        token_stream_matchers::internal::mismatch_tokens(
            &ir_to_token_stream(ir).expect("Failed to convert IR to token stream"),
            pattern,
            ir_to_string,
        )
        .unwrap()
    }

    fn ir_to_token_stream(ir: &IR) -> Result<TokenStream> {
        // derived debug impl doesn't emit commas after the last element of a group,
        // (for example `[a, b, c]`), but rustfmt automatically adds it (`[a, b,
        // c,]`). We use rustfmt to format the failure messages. So to make the
        // input token stream consistent with failure messages we format the
        // input token stream with rustfmt as well.
        Ok(ir_to_string(ir.flat_ir_debug_print().parse().unwrap())?.parse().unwrap())
    }

    fn ir_to_string(input: TokenStream) -> Result<String> {
        // Rustfmt refuses to format some kinds of invalid Rust code. Let's put our IR
        // struct expression into the body of a function, format it, and then remove
        // the function.
        let input_stream = quote! { fn make_rustfmt_happy() { #input } };
        let formatted = rs_tokens_to_formatted_string_for_tests(input_stream)?;
        let snippet = formatted
            .strip_prefix("fn make_rustfmt_happy() {\n")
            .unwrap()
            .strip_suffix("}\n")
            .unwrap()
            .lines()
            .map(|line| &line[4..])
            .join("\n");
        Ok(snippet)
    }

    #[track_caller]
    pub fn assert_items_match_fn(items: &[&Item], patterns: &[TokenStream]) {
        assert_eq!(items.len(), patterns.len());
        for (idx, (item, pattern)) in items.iter().zip(patterns).enumerate() {
            if match_item(item, pattern).is_err() {
                panic!("input at position `{idx}` unexpectedly didn't match the pattern")
            }
        }
    }

    fn match_item(item: &Item, pattern: &TokenStream) -> Result<()> {
        token_stream_matchers::internal::match_tokens(
            &item_to_token_stream(item)?,
            pattern,
            ir_to_string,
        )
    }

    fn item_to_token_stream(item: &Item) -> Result<TokenStream> {
        // derived debug impl doesn't emit commas after the last element of a group,
        // (for example `[a, b, c]`), but rustfmt automatically adds it (`[a, b,
        // c,]`). We use rustfmt to format the failure messages. So to make the
        // input token stream consistent with failure messages we format the
        // input token stream with rustfmt as well.
        Ok(ir_to_string(format! {"{:?}", item}.parse().unwrap())?.parse().unwrap())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use googletest::prelude::*;
    use quote::quote;

    /// We aren't testing platform-specific details, just the matchers.
    fn ir_from_cc(header: &str) -> arc_anyhow::Result<ir::IR> {
        ir_testing::ir_from_cc(multiplatform_testing::Platform::X86Linux, header)
    }

    #[gtest]
    fn test_optional_trailing_comma() {
        assert_ir_matches!(ir_from_cc("").unwrap(), quote! { FlatIR { ... }});
        assert_ir_matches!(ir_from_cc("").unwrap(), quote! { FlatIR { ... }},);

        assert_ir_not_matches!(ir_from_cc("").unwrap(), quote! {this pattern is not in the ir});
        assert_ir_not_matches!(ir_from_cc("").unwrap(), quote! {this pattern is not in the ir},);
    }

    #[gtest]
    fn test_assert_ir_matches_assumes_trailing_commas_in_groups() {
        assert_ir_matches!(ir_from_cc("").unwrap(), quote! {{... , }});
    }

    #[gtest]
    fn test_assert_not_matches_accepts_not_matching_pattern() {
        assert_ir_not_matches!(ir_from_cc("").unwrap(), quote! {this pattern is not in the ir});
    }

    #[gtest]
    #[should_panic(expected = "input:\n\n```\nFlatIR {")]
    fn test_assert_ir_not_matches_panics_on_match() {
        assert_ir_not_matches!(ir_from_cc("").unwrap(), quote! {items});
    }

    #[gtest]
    #[should_panic]
    fn test_assert_ir_matches_panics_on_mismatch() {
        assert_ir_matches!(ir_from_cc("").unwrap(), quote! {this pattern is not in the ir});
    }
}
