#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

NS_INLINE NSBundle *{{ job.swiftIdentifier | objc_symbol_part }}__Bundle(void) {
{% if bundle.mode == "main" -%}
    return NSBundle.mainBundle;
{% elif bundle.mode == "module" -%}
#if defined(SWIFTPM_MODULE_BUNDLE)
    return SWIFTPM_MODULE_BUNDLE;
#else
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:@"SWIFTPM_MODULE_BUNDLE is unavailable for module-scoped ObjC resources."
                                 userInfo:nil];
#endif
{% elif bundle.mode == "custom" -%}
    NSBundle *bundle = [NSBundle bundleWithIdentifier:{{ bundle.identifier | objc_string_literal }}];
    if (bundle == nil) {
        @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                       reason:{{ ("Missing configured bundle identifier: " ~ bundle.identifier) | objc_string_literal }}
                                     userInfo:nil];
    }
    return bundle;
{% else -%}
    @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                   reason:{{ ("Unsupported bundle mode: " ~ bundle.mode) | objc_string_literal }}
                                 userInfo:nil];
{% endif -%}
}

NS_INLINE NSURL *{{ job.swiftIdentifier | objc_symbol_part }}__FileURL(NSString *path) {
    NSURL *url = [{{ job.swiftIdentifier | objc_symbol_part }}__Bundle() URLForResource:path withExtension:nil];
    if (url == nil) {
        @throw [NSException exceptionWithName:NSInternalInconsistencyException
                                       reason:[NSString stringWithFormat:@"Missing file resource: %@", path]
                                     userInfo:nil];
    }
    return url;
}

{% macro render_entries(entries, prefix) -%}
{% for entry in entries -%}
{% if entry.kind == "namespace" -%}
{{ render_entries(entry.children, prefix ~ (entry.swiftIdentifier | objc_symbol_part) ~ "__") }}{% elif entry.kind == "data" -%}
NS_INLINE NSURL *{{ job.swiftIdentifier | objc_symbol_part }}__{{ prefix }}{{ entry.swiftIdentifier | objc_symbol_part }}(void) {
    return {{ job.swiftIdentifier | objc_symbol_part }}__FileURL({{ entry.properties.relativePath | objc_string_literal }});
}

{% endif -%}
{% endfor -%}
{%- endmacro %}
{% for module in modules %}
{{ render_entries(module.entries, (module.name | objc_symbol_part) ~ "__") }}{% endfor -%}
NS_ASSUME_NONNULL_END
