use minijinja::Environment;

static TEMPLATES: &[(&str, &str)] = &[
    // Dart class headers
    ("class_header.jinja", include_str!("templates/class_header.jinja")),
    ("class_empty.jinja", include_str!("templates/class_empty.jinja")),
    ("class_open.jinja", include_str!("templates/class_open.jinja")),
    ("class_close.jinja", include_str!("templates/class_close.jinja")),
    // Freezed class headers
    (
        "freezed_class_open.jinja",
        include_str!("templates/freezed_class_open.jinja"),
    ),
    (
        "freezed_class_single_param.jinja",
        include_str!("templates/freezed_class_single_param.jinja"),
    ),
    (
        "freezed_constructor_close.jinja",
        include_str!("templates/freezed_constructor_close.jinja"),
    ),
    (
        "freezed_required_param.jinja",
        include_str!("templates/freezed_required_param.jinja"),
    ),
    // Enum declarations
    ("enum_header.jinja", include_str!("templates/enum_header.jinja")),
    ("enum_close.jinja", include_str!("templates/enum_close.jinja")),
    (
        "enum_unit_variant.jinja",
        include_str!("templates/enum_unit_variant.jinja"),
    ),
    (
        "sealed_class_header.jinja",
        include_str!("templates/sealed_class_header.jinja"),
    ),
    (
        "final_class_header.jinja",
        include_str!("templates/final_class_header.jinja"),
    ),
    (
        "final_class_extends.jinja",
        include_str!("templates/final_class_extends.jinja"),
    ),
    // Field and property declarations
    (
        "final_field_decl.jinja",
        include_str!("templates/final_field_decl.jinja"),
    ),
    (
        "override_message_getter.jinja",
        include_str!("templates/override_message_getter.jinja"),
    ),
    // Constructors
    (
        "single_param_constructor.jinja",
        include_str!("templates/single_param_constructor.jinja"),
    ),
    (
        "multi_param_constructor_open.jinja",
        include_str!("templates/multi_param_constructor_open.jinja"),
    ),
    (
        "const_constructor.jinja",
        include_str!("templates/const_constructor.jinja"),
    ),
    (
        "constructor_required_param.jinja",
        include_str!("templates/constructor_required_param.jinja"),
    ),
    (
        "constructor_close.jinja",
        include_str!("templates/constructor_close.jinja"),
    ),
    // Error classes
    (
        "error_sealed_class.jinja",
        include_str!("templates/error_sealed_class.jinja"),
    ),
    (
        "error_message_property.jinja",
        include_str!("templates/error_message_property.jinja"),
    ),
    // FFI functions
    (
        "ffi_typedef_native.jinja",
        include_str!("templates/ffi_typedef_native.jinja"),
    ),
    (
        "ffi_typedef_dart.jinja",
        include_str!("templates/ffi_typedef_dart.jinja"),
    ),
    (
        "ffi_function_lookup.jinja",
        include_str!("templates/ffi_function_lookup.jinja"),
    ),
    (
        "ffi_native_alloc.jinja",
        include_str!("templates/ffi_native_alloc.jinja"),
    ),
    ("ffi_call_result.jinja", include_str!("templates/ffi_call_result.jinja")),
    ("ffi_call_void.jinja", include_str!("templates/ffi_call_void.jinja")),
    ("ffi_free_native.jinja", include_str!("templates/ffi_free_native.jinja")),
    (
        "ffi_return_unwrapped.jinja",
        include_str!("templates/ffi_return_unwrapped.jinja"),
    ),
    (
        "dart_ffi_file_header.jinja",
        include_str!("templates/dart_ffi_file_header.jinja"),
    ),
    (
        "dart_ffi_wrapper_file.jinja",
        include_str!("templates/dart_ffi_wrapper_file.jinja"),
    ),
    (
        "ffi_lib_path_macos.jinja",
        include_str!("templates/ffi_lib_path_macos.jinja"),
    ),
    (
        "ffi_lib_path_windows.jinja",
        include_str!("templates/ffi_lib_path_windows.jinja"),
    ),
    (
        "ffi_lib_path_linux.jinja",
        include_str!("templates/ffi_lib_path_linux.jinja"),
    ),
    // FFI error helpers
    (
        "ffi_free_string_lookup.jinja",
        include_str!("templates/ffi_free_string_lookup.jinja"),
    ),
    (
        "ffi_last_error_code_lookup.jinja",
        include_str!("templates/ffi_last_error_code_lookup.jinja"),
    ),
    (
        "ffi_last_error_context_lookup.jinja",
        include_str!("templates/ffi_last_error_context_lookup.jinja"),
    ),
    // Bridge and trait functions
    (
        "function_signature_async.jinja",
        include_str!("templates/function_signature_async.jinja"),
    ),
    (
        "function_signature_sync.jinja",
        include_str!("templates/function_signature_sync.jinja"),
    ),
    (
        "function_throws_annotation.jinja",
        include_str!("templates/function_throws_annotation.jinja"),
    ),
    (
        "function_await_return.jinja",
        include_str!("templates/function_await_return.jinja"),
    ),
    (
        "function_sync_return.jinja",
        include_str!("templates/function_sync_return.jinja"),
    ),
    // Trait bridges (Rust side)
    (
        "trait_struct_open.jinja",
        include_str!("templates/trait_struct_open.jinja"),
    ),
    (
        "trait_struct_close.jinja",
        include_str!("templates/trait_struct_close.jinja"),
    ),
    ("trait_impl_open.jinja", include_str!("templates/trait_impl_open.jinja")),
    (
        "trait_impl_close.jinja",
        include_str!("templates/trait_impl_close.jinja"),
    ),
    (
        "trait_method_field.jinja",
        include_str!("templates/trait_method_field.jinja"),
    ),
    (
        "trait_method_closure.jinja",
        include_str!("templates/trait_method_closure.jinja"),
    ),
    (
        "plugin_impl_open.jinja",
        include_str!("templates/plugin_impl_open.jinja"),
    ),
    (
        "plugin_impl_close.jinja",
        include_str!("templates/plugin_impl_close.jinja"),
    ),
    (
        "plugin_name_method.jinja",
        include_str!("templates/plugin_name_method.jinja"),
    ),
    (
        "plugin_version_method.jinja",
        include_str!("templates/plugin_version_method.jinja"),
    ),
    (
        "plugin_initialize_method.jinja",
        include_str!("templates/plugin_initialize_method.jinja"),
    ),
    (
        "plugin_shutdown_method.jinja",
        include_str!("templates/plugin_shutdown_method.jinja"),
    ),
    // Trait abstracts and documentation
    (
        "abstract_class_header.jinja",
        include_str!("templates/abstract_class_header.jinja"),
    ),
    (
        "abstract_class_doc_comment.jinja",
        include_str!("templates/abstract_class_doc_comment.jinja"),
    ),
    (
        "abstract_class_doc_code_start.jinja",
        include_str!("templates/abstract_class_doc_code_start.jinja"),
    ),
    (
        "abstract_class_doc_code_impl.jinja",
        include_str!("templates/abstract_class_doc_code_impl.jinja"),
    ),
    (
        "abstract_class_doc_code_create.jinja",
        include_str!("templates/abstract_class_doc_code_create.jinja"),
    ),
    (
        "abstract_class_doc_code_end.jinja",
        include_str!("templates/abstract_class_doc_code_end.jinja"),
    ),
    ("doc_comment.jinja", include_str!("templates/doc_comment.jinja")),
    (
        "abstract_method_declaration.jinja",
        include_str!("templates/abstract_method_declaration.jinja"),
    ),
    // Rust bridge declarations
    (
        "frb_pub_async_fn.jinja",
        include_str!("templates/frb_pub_async_fn.jinja"),
    ),
    ("frb_pub_sync_fn.jinja", include_str!("templates/frb_pub_sync_fn.jinja")),
    (
        "frb_fn_body_open.jinja",
        include_str!("templates/frb_fn_body_open.jinja"),
    ),
    (
        "frb_fn_body_close.jinja",
        include_str!("templates/frb_fn_body_close.jinja"),
    ),
    (
        "frb_result_ok_cast.jinja",
        include_str!("templates/frb_result_ok_cast.jinja"),
    ),
    (
        "frb_result_ok_method.jinja",
        include_str!("templates/frb_result_ok_method.jinja"),
    ),
    ("frb_result_cast.jinja", include_str!("templates/frb_result_cast.jinja")),
    (
        "frb_result_method.jinja",
        include_str!("templates/frb_result_method.jinja"),
    ),
    (
        "frb_result_await_method.jinja",
        include_str!("templates/frb_result_await_method.jinja"),
    ),
    (
        "frb_result_block_on.jinja",
        include_str!("templates/frb_result_block_on.jinja"),
    ),
    // Trait impl items
    (
        "trait_factory_fn_open.jinja",
        include_str!("templates/trait_factory_fn_open.jinja"),
    ),
    (
        "trait_factory_fn_close.jinja",
        include_str!("templates/trait_factory_fn_close.jinja"),
    ),
    (
        "trait_factory_param.jinja",
        include_str!("templates/trait_factory_param.jinja"),
    ),
    (
        "mirror_struct_open.jinja",
        include_str!("templates/mirror_struct_open.jinja"),
    ),
    (
        "mirror_struct_close.jinja",
        include_str!("templates/mirror_struct_close.jinja"),
    ),
    (
        "mirror_pub_field.jinja",
        include_str!("templates/mirror_pub_field.jinja"),
    ),
    // Rust bridge and mirror declarations
    (
        "rust_bridge_fn_open.jinja",
        include_str!("templates/rust_bridge_fn_open.jinja"),
    ),
    (
        "rust_bridge_stub_body.rs.jinja",
        include_str!("templates/rust_bridge_stub_body.rs.jinja"),
    ),
    ("rust_pub_use.rs.jinja", include_str!("templates/rust_pub_use.rs.jinja")),
    ("rust_use.rs.jinja", include_str!("templates/rust_use.rs.jinja")),
    (
        "rust_impl_open.rs.jinja",
        include_str!("templates/rust_impl_open.rs.jinja"),
    ),
    (
        "rust_client_constructor_impl.rs.jinja",
        include_str!("templates/rust_client_constructor_impl.rs.jinja"),
    ),
    (
        "rust_streaming_sink_method.rs.jinja",
        include_str!("templates/rust_streaming_sink_method.rs.jinja"),
    ),
    (
        "rust_opaque_method_open.rs.jinja",
        include_str!("templates/rust_opaque_method_open.rs.jinja"),
    ),
    (
        "rust_static_opaque_method_open.rs.jinja",
        include_str!("templates/rust_static_opaque_method_open.rs.jinja"),
    ),
    (
        "rust_opaque_call_await_error.rs.jinja",
        include_str!("templates/rust_opaque_call_await_error.rs.jinja"),
    ),
    (
        "rust_opaque_call_await_map_error.rs.jinja",
        include_str!("templates/rust_opaque_call_await_map_error.rs.jinja"),
    ),
    (
        "rust_opaque_call_await.rs.jinja",
        include_str!("templates/rust_opaque_call_await.rs.jinja"),
    ),
    (
        "rust_opaque_call_wrap_await.rs.jinja",
        include_str!("templates/rust_opaque_call_wrap_await.rs.jinja"),
    ),
    (
        "rust_opaque_call_error.rs.jinja",
        include_str!("templates/rust_opaque_call_error.rs.jinja"),
    ),
    (
        "rust_opaque_call_map_error.rs.jinja",
        include_str!("templates/rust_opaque_call_map_error.rs.jinja"),
    ),
    (
        "rust_opaque_call.rs.jinja",
        include_str!("templates/rust_opaque_call.rs.jinja"),
    ),
    (
        "rust_opaque_call_wrap.rs.jinja",
        include_str!("templates/rust_opaque_call_wrap.rs.jinja"),
    ),
    (
        "rust_from_json_bridge_fn.rs.jinja",
        include_str!("templates/rust_from_json_bridge_fn.rs.jinja"),
    ),
    (
        "rust_skipped_sanitized_method_comment.rs.jinja",
        include_str!("templates/rust_skipped_sanitized_method_comment.rs.jinja"),
    ),
    (
        "rust_error_impl_open.rs.jinja",
        include_str!("templates/rust_error_impl_open.rs.jinja"),
    ),
    (
        "rust_error_method_open.rs.jinja",
        include_str!("templates/rust_error_method_open.rs.jinja"),
    ),
    (
        "rust_error_method_body.rs.jinja",
        include_str!("templates/rust_error_method_body.rs.jinja"),
    ),
    (
        "rust_mirror_struct_open.jinja",
        include_str!("templates/rust_mirror_struct_open.jinja"),
    ),
    (
        "rust_mirror_struct_field.jinja",
        include_str!("templates/rust_mirror_struct_field.jinja"),
    ),
    (
        "rust_mirror_struct_close.jinja",
        include_str!("templates/rust_mirror_struct_close.jinja"),
    ),
    (
        "rust_mirror_enum_open.jinja",
        include_str!("templates/rust_mirror_enum_open.jinja"),
    ),
    (
        "rust_mirror_enum_unit_variant.jinja",
        include_str!("templates/rust_mirror_enum_unit_variant.jinja"),
    ),
    (
        "rust_mirror_enum_data_variant_open.jinja",
        include_str!("templates/rust_mirror_enum_data_variant_open.jinja"),
    ),
    (
        "rust_mirror_enum_data_variant_field.jinja",
        include_str!("templates/rust_mirror_enum_data_variant_field.jinja"),
    ),
    (
        "rust_mirror_error_from_impl_open.rs.jinja",
        include_str!("templates/rust_mirror_error_from_impl_open.rs.jinja"),
    ),
    (
        "rust_mirror_error_unit_from_arm.rs.jinja",
        include_str!("templates/rust_mirror_error_unit_from_arm.rs.jinja"),
    ),
    (
        "rust_mirror_error_excluded_from_arm.rs.jinja",
        include_str!("templates/rust_mirror_error_excluded_from_arm.rs.jinja"),
    ),
    (
        "rust_mirror_error_struct_pattern_arm.rs.jinja",
        include_str!("templates/rust_mirror_error_struct_pattern_arm.rs.jinja"),
    ),
    (
        "rust_mirror_error_tuple_return.rs.jinja",
        include_str!("templates/rust_mirror_error_tuple_return.rs.jinja"),
    ),
    (
        "rust_mirror_error_struct_return.rs.jinja",
        include_str!("templates/rust_mirror_error_struct_return.rs.jinja"),
    ),
    (
        "rust_mirror_error_sanitized_wildcard_arm.rs.jinja",
        include_str!("templates/rust_mirror_error_sanitized_wildcard_arm.rs.jinja"),
    ),
    (
        "rust_mirror_error_from_impl_close.rs.jinja",
        include_str!("templates/rust_mirror_error_from_impl_close.rs.jinja"),
    ),
    (
        "rust_cargo_target_dependency.rs.jinja",
        include_str!("templates/rust_cargo_target_dependency.rs.jinja"),
    ),
    (
        "rust_cargo_toml.rs.jinja",
        include_str!("templates/rust_cargo_toml.rs.jinja"),
    ),
    (
        "rust_build_rs.rs.jinja",
        include_str!("templates/rust_build_rs.rs.jinja"),
    ),
    (
        "rust_loader_patch_fn.rs.jinja",
        include_str!("templates/rust_loader_patch_fn.rs.jinja"),
    ),
    (
        "dart_init_prologue_replacement.jinja",
        include_str!("templates/dart_init_prologue_replacement.jinja"),
    ),
    (
        "flutter_rust_bridge_yaml.jinja",
        include_str!("templates/flutter_rust_bridge_yaml.jinja"),
    ),
    (
        "rust_enum_stripped_tuple_to_core_arm.jinja",
        include_str!("templates/rust_enum_stripped_tuple_to_core_arm.jinja"),
    ),
    (
        "rust_enum_stripped_struct_to_core_arm.jinja",
        include_str!("templates/rust_enum_stripped_struct_to_core_arm.jinja"),
    ),
    // Rust trait factory and methods
    (
        "rust_trait_factory_doc.jinja",
        include_str!("templates/rust_trait_factory_doc.jinja"),
    ),
    (
        "rust_trait_factory_fn.jinja",
        include_str!("templates/rust_trait_factory_fn.jinja"),
    ),
    (
        "rust_trait_factory_param.jinja",
        include_str!("templates/rust_trait_factory_param.jinja"),
    ),
    (
        "rust_trait_factory_return.jinja",
        include_str!("templates/rust_trait_factory_return.jinja"),
    ),
    (
        "rust_trait_factory_method_field.jinja",
        include_str!("templates/rust_trait_factory_method_field.jinja"),
    ),
    (
        "rust_trait_factory_struct_init.jinja",
        include_str!("templates/rust_trait_factory_struct_init.jinja"),
    ),
    (
        "rust_trait_factory_method_init.jinja",
        include_str!("templates/rust_trait_factory_method_init.jinja"),
    ),
    (
        "rust_trait_type_alias_factory_doc.jinja",
        include_str!("templates/rust_trait_type_alias_factory_doc.jinja"),
    ),
    (
        "rust_trait_type_alias_factory_open.jinja",
        include_str!("templates/rust_trait_type_alias_factory_open.jinja"),
    ),
    (
        "rust_trait_type_alias_factory_param.jinja",
        include_str!("templates/rust_trait_type_alias_factory_param.jinja"),
    ),
    (
        "rust_trait_type_alias_factory_body.jinja",
        include_str!("templates/rust_trait_type_alias_factory_body.jinja"),
    ),
    (
        "rust_trait_options_from_json_with_field.jinja",
        include_str!("templates/rust_trait_options_from_json_with_field.jinja"),
    ),
    (
        "rust_trait_method_param_conversion.jinja",
        include_str!("templates/rust_trait_method_param_conversion.jinja"),
    ),
    (
        "rust_trait_method_plain_result.jinja",
        include_str!("templates/rust_trait_method_plain_result.jinja"),
    ),
    (
        "rust_trait_method_await_plain.jinja",
        include_str!("templates/rust_trait_method_await_plain.jinja"),
    ),
    (
        "rust_trait_method_await_result.jinja",
        include_str!("templates/rust_trait_method_await_result.jinja"),
    ),
    (
        "rust_trait_method_default_await.jinja",
        include_str!("templates/rust_trait_method_default_await.jinja"),
    ),
    (
        "rust_trait_method_default_from_result.jinja",
        include_str!("templates/rust_trait_method_default_from_result.jinja"),
    ),
    (
        "rust_trait_method_plain_block_on_result.jinja",
        include_str!("templates/rust_trait_method_plain_block_on_result.jinja"),
    ),
    (
        "rust_trait_method_block_on.jinja",
        include_str!("templates/rust_trait_method_block_on.jinja"),
    ),
    (
        "rust_trait_method_ok_await.jinja",
        include_str!("templates/rust_trait_method_ok_await.jinja"),
    ),
    (
        "rust_trait_method_ok_block_on.jinja",
        include_str!("templates/rust_trait_method_ok_block_on.jinja"),
    ),
    (
        "rust_trait_method_await_plain_spawn_blocking.jinja",
        include_str!("templates/rust_trait_method_await_plain_spawn_blocking.jinja"),
    ),
    (
        "rust_trait_method_await_result_spawn_blocking.jinja",
        include_str!("templates/rust_trait_method_await_result_spawn_blocking.jinja"),
    ),
    (
        "rust_trait_method_default_await_spawn_blocking.jinja",
        include_str!("templates/rust_trait_method_default_await_spawn_blocking.jinja"),
    ),
    (
        "rust_trait_method_ok_await_spawn_blocking.jinja",
        include_str!("templates/rust_trait_method_ok_await_spawn_blocking.jinja"),
    ),
    (
        "rust_trait_excluded_async_result_return.rs.jinja",
        include_str!("templates/rust_trait_excluded_async_result_return.rs.jinja"),
    ),
    (
        "rust_trait_excluded_async_plain_return.rs.jinja",
        include_str!("templates/rust_trait_excluded_async_plain_return.rs.jinja"),
    ),
    (
        "rust_trait_excluded_block_on_result_return.rs.jinja",
        include_str!("templates/rust_trait_excluded_block_on_result_return.rs.jinja"),
    ),
    (
        "rust_trait_excluded_block_on_plain_return.rs.jinja",
        include_str!("templates/rust_trait_excluded_block_on_plain_return.rs.jinja"),
    ),
    (
        "rust_trait_register_forwarder.jinja",
        include_str!("templates/rust_trait_register_forwarder.jinja"),
    ),
    (
        "rust_trait_unregister_forwarder.jinja",
        include_str!("templates/rust_trait_unregister_forwarder.jinja"),
    ),
    (
        "rust_trait_clear_forwarder.jinja",
        include_str!("templates/rust_trait_clear_forwarder.jinja"),
    ),
    (
        "rust_from_core_struct_open.jinja",
        include_str!("templates/rust_from_core_struct_open.jinja"),
    ),
    (
        "rust_from_mirror_struct_open.jinja",
        include_str!("templates/rust_from_mirror_struct_open.jinja"),
    ),
    (
        "rust_from_core_enum_open.jinja",
        include_str!("templates/rust_from_core_enum_open.jinja"),
    ),
    (
        "rust_from_mirror_enum_open.jinja",
        include_str!("templates/rust_from_mirror_enum_open.jinja"),
    ),
    (
        "rust_from_impl_close.jinja",
        include_str!("templates/rust_from_impl_close.jinja"),
    ),
    // Error class, bridge class, and extra templates
    (
        "error_class_header.jinja",
        include_str!("templates/error_class_header.jinja"),
    ),
    (
        "abstract_class_method_doc_line.jinja",
        include_str!("templates/abstract_class_method_doc_line.jinja"),
    ),
    (
        "trait_method_doc_field.jinja",
        include_str!("templates/trait_method_doc_field.jinja"),
    ),
    (
        "rust_trait_struct_field.jinja",
        include_str!("templates/rust_trait_struct_field.jinja"),
    ),
    (
        "rust_callbacks_debug_impl.rs.jinja",
        include_str!("templates/rust_callbacks_debug_impl.rs.jinja"),
    ),
    (
        "rust_trait_reexport_opaque_wrapper.rs.jinja",
        include_str!("templates/rust_trait_reexport_opaque_wrapper.rs.jinja"),
    ),
    (
        "rust_trait_plugin_factory_open.rs.jinja",
        include_str!("templates/rust_trait_plugin_factory_open.rs.jinja"),
    ),
    (
        "rust_trait_plugin_factory_doc.rs.jinja",
        include_str!("templates/rust_trait_plugin_factory_doc.rs.jinja"),
    ),
    (
        "rust_trait_plugin_factory_body.rs.jinja",
        include_str!("templates/rust_trait_plugin_factory_body.rs.jinja"),
    ),
    (
        "rust_excluded_carrier.rs.jinja",
        include_str!("templates/rust_excluded_carrier.rs.jinja"),
    ),
    (
        "rust_trait_impl_open.jinja",
        include_str!("templates/rust_trait_impl_open.jinja"),
    ),
    (
        "rust_trait_struct_init_open.jinja",
        include_str!("templates/rust_trait_struct_init_open.jinja"),
    ),
    (
        "rust_plugin_impl_open.jinja",
        include_str!("templates/rust_plugin_impl_open.jinja"),
    ),
    (
        "rust_plugin_initialize.jinja",
        include_str!("templates/rust_plugin_initialize.jinja"),
    ),
    (
        "rust_plugin_shutdown.jinja",
        include_str!("templates/rust_plugin_shutdown.jinja"),
    ),
    (
        "rust_method_signature.jinja",
        include_str!("templates/rust_method_signature.jinja"),
    ),
    (
        "rust_mirror_struct_attribute.jinja",
        include_str!("templates/rust_mirror_struct_attribute.jinja"),
    ),
    (
        "rust_opaque_wrapper_struct.jinja",
        include_str!("templates/rust_opaque_wrapper_struct.jinja"),
    ),
    (
        "rust_mirror_enum_attribute.jinja",
        include_str!("templates/rust_mirror_enum_attribute.jinja"),
    ),
    (
        "rust_mirror_enum_variant_line.jinja",
        include_str!("templates/rust_mirror_enum_variant_line.jinja"),
    ),
    (
        "rust_mirror_enum_data_close.jinja",
        include_str!("templates/rust_mirror_enum_data_close.jinja"),
    ),
    (
        "dart_bridge_class_open.jinja",
        include_str!("templates/dart_bridge_class_open.jinja"),
    ),
    (
        "dart_bridge_export.jinja",
        include_str!("templates/dart_bridge_export.jinja"),
    ),
    (
        "dart_bridge_import.jinja",
        include_str!("templates/dart_bridge_import.jinja"),
    ),
    (
        "dart_bridge_imports.jinja",
        include_str!("templates/dart_bridge_imports.jinja"),
    ),
    (
        "dart_barrel_file.jinja",
        include_str!("templates/dart_barrel_file.jinja"),
    ),
    (
        "dart_trait_register_method.jinja",
        include_str!("templates/dart_trait_register_method.jinja"),
    ),
    (
        "dart_trait_unregister_method.jinja",
        include_str!("templates/dart_trait_unregister_method.jinja"),
    ),
    (
        "dart_trait_clear_method.jinja",
        include_str!("templates/dart_trait_clear_method.jinja"),
    ),
    (
        "rust_struct_field_assignment.jinja",
        include_str!("templates/rust_struct_field_assignment.jinja"),
    ),
    (
        "rust_enum_unit_to_core_arm.jinja",
        include_str!("templates/rust_enum_unit_to_core_arm.jinja"),
    ),
    (
        "rust_enum_tuple_to_core_arm.jinja",
        include_str!("templates/rust_enum_tuple_to_core_arm.jinja"),
    ),
    (
        "rust_enum_struct_to_core_arm.jinja",
        include_str!("templates/rust_enum_struct_to_core_arm.jinja"),
    ),
    (
        "rust_enum_unit_from_core_arm.jinja",
        include_str!("templates/rust_enum_unit_from_core_arm.jinja"),
    ),
    (
        "rust_enum_tuple_from_core_arm.jinja",
        include_str!("templates/rust_enum_tuple_from_core_arm.jinja"),
    ),
    (
        "rust_enum_struct_from_core_arm.jinja",
        include_str!("templates/rust_enum_struct_from_core_arm.jinja"),
    ),
    (
        "rust_enum_struct_stripped_from_core_arm.jinja",
        include_str!("templates/rust_enum_struct_stripped_from_core_arm.jinja"),
    ),
    (
        "rust_enum_tuple_stripped_from_core_arm.jinja",
        include_str!("templates/rust_enum_tuple_stripped_from_core_arm.jinja"),
    ),
    (
        "rust_enum_excluded_variant_tuple_arm.jinja",
        include_str!("templates/rust_enum_excluded_variant_tuple_arm.jinja"),
    ),
    (
        "rust_enum_excluded_variant_unit_arm.jinja",
        include_str!("templates/rust_enum_excluded_variant_unit_arm.jinja"),
    ),
    (
        "enum_data_variants_todo.jinja",
        include_str!("templates/enum_data_variants_todo.jinja"),
    ),
    (
        "ffi_lib_path_macos_return.jinja",
        include_str!("templates/ffi_lib_path_macos_return.jinja"),
    ),
    (
        "ffi_lib_path_windows_return.jinja",
        include_str!("templates/ffi_lib_path_windows_return.jinja"),
    ),
    (
        "ffi_lib_path_linux_return.jinja",
        include_str!("templates/ffi_lib_path_linux_return.jinja"),
    ),
    ("ffi_async_todo.jinja", include_str!("templates/ffi_async_todo.jinja")),
    (
        "ffi_error_throws_doc.jinja",
        include_str!("templates/ffi_error_throws_doc.jinja"),
    ),
    (
        "ffi_typedef_native_sig.jinja",
        include_str!("templates/ffi_typedef_native_sig.jinja"),
    ),
    (
        "ffi_typedef_dart_sig.jinja",
        include_str!("templates/ffi_typedef_dart_sig.jinja"),
    ),
    (
        "ffi_function_lookup_sig.jinja",
        include_str!("templates/ffi_function_lookup_sig.jinja"),
    ),
    (
        "ffi_wrapper_fn_open.jinja",
        include_str!("templates/ffi_wrapper_fn_open.jinja"),
    ),
    (
        "ffi_param_alloc_string.jinja",
        include_str!("templates/ffi_param_alloc_string.jinja"),
    ),
    (
        "ffi_return_value.jinja",
        include_str!("templates/ffi_return_value.jinja"),
    ),
    (
        "ffi_param_free_string.jinja",
        include_str!("templates/ffi_param_free_string.jinja"),
    ),
    (
        "dart_streaming_method.jinja",
        include_str!("templates/dart_streaming_method.jinja"),
    ),
    // Service API templates (Rust FRB-opaque service owners and handler bridges)
    (
        "service_api/file_header.rs.jinja",
        include_str!("templates/service_api/file_header.rs.jinja"),
    ),
    (
        "service_api/handler_bridge_doc.rs.jinja",
        include_str!("templates/service_api/handler_bridge_doc.rs.jinja"),
    ),
    (
        "service_api/handler_bridge_struct.rs.jinja",
        include_str!("templates/service_api/handler_bridge_struct.rs.jinja"),
    ),
    (
        "service_api/handler_bridge_constructor.rs.jinja",
        include_str!("templates/service_api/handler_bridge_constructor.rs.jinja"),
    ),
    (
        "service_api/handler_bridge_impl_open.rs.jinja",
        include_str!("templates/service_api/handler_bridge_impl_open.rs.jinja"),
    ),
    (
        "service_api/dart_registration_struct.rs.jinja",
        include_str!("templates/service_api/dart_registration_struct.rs.jinja"),
    ),
    (
        "service_api/service_owner_doc.rs.jinja",
        include_str!("templates/service_api/service_owner_doc.rs.jinja"),
    ),
    (
        "service_api/default_service_owner_doc.rs.jinja",
        include_str!("templates/service_api/default_service_owner_doc.rs.jinja"),
    ),
    (
        "service_api/service_owner_struct.rs.jinja",
        include_str!("templates/service_api/service_owner_struct.rs.jinja"),
    ),
    (
        "service_api/service_owner_impl_open.rs.jinja",
        include_str!("templates/service_api/service_owner_impl_open.rs.jinja"),
    ),
    (
        "service_api/configurator_method.rs.jinja",
        include_str!("templates/service_api/configurator_method.rs.jinja"),
    ),
    (
        "service_api/method_param.rs.jinja",
        include_str!("templates/service_api/method_param.rs.jinja"),
    ),
    (
        "service_api/registration_method.rs.jinja",
        include_str!("templates/service_api/registration_method.rs.jinja"),
    ),
    (
        "service_api/registration_variant.rs.jinja",
        include_str!("templates/service_api/registration_variant.rs.jinja"),
    ),
    (
        "service_api/entrypoint_method.rs.jinja",
        include_str!("templates/service_api/entrypoint_method.rs.jinja"),
    ),
    (
        "service_api/service_owner_impl_close.rs.jinja",
        include_str!("templates/service_api/service_owner_impl_close.rs.jinja"),
    ),
    (
        "bin_download_libs.jinja",
        include_str!("templates/bin_download_libs.jinja"),
    ),
];

pub(crate) fn make_env() -> Environment<'static> {
    let mut env = Environment::new();
    env.set_trim_blocks(true);
    env.set_lstrip_blocks(true);
    env.set_keep_trailing_newline(true);
    for (name, src) in TEMPLATES {
        env.add_template(name, src)
            .unwrap_or_else(|e| panic!("failed to add template {name}: {e}"));
    }
    env
}

pub(crate) fn render(template_name: &str, ctx: minijinja::Value) -> String {
    make_env()
        .get_template(template_name)
        .unwrap_or_else(|_| panic!("template {template_name} not found"))
        .render(ctx)
        .unwrap_or_else(|e| panic!("template {template_name} failed to render: {e}"))
}
