use minijinja::Environment;

static TEMPLATES: &[(&str, &str)] = &[
    (
        "python/pyproject.toml.jinja",
        include_str!("templates/python/pyproject.toml.jinja"),
    ),
    (
        "python/conftest.py.jinja",
        include_str!("templates/python/conftest.py.jinja"),
    ),
    (
        "python/assertion.jinja",
        include_str!("templates/python/assertion.jinja"),
    ),
    (
        "python/visitor_method.jinja",
        include_str!("templates/python/visitor_method.jinja"),
    ),
    (
        "python/test_file.jinja",
        include_str!("templates/python/test_file.jinja"),
    ),
    (
        "python/test_function.jinja",
        include_str!("templates/python/test_function.jinja"),
    ),
    ("ruby/Gemfile.jinja", include_str!("templates/ruby/Gemfile.jinja")),
    (
        "ruby/rubocop.yml.jinja",
        include_str!("templates/ruby/rubocop.yml.jinja"),
    ),
    ("ruby/assertion.jinja", include_str!("templates/ruby/assertion.jinja")),
    (
        "ruby/visitor_method.jinja",
        include_str!("templates/ruby/visitor_method.jinja"),
    ),
    ("ruby/test_file.jinja", include_str!("templates/ruby/test_file.jinja")),
    (
        "ruby/test_function.jinja",
        include_str!("templates/ruby/test_function.jinja"),
    ),
    ("ruby/http_test.jinja", include_str!("templates/ruby/http_test.jinja")),
    (
        "ruby/http_test_close.jinja",
        include_str!("templates/ruby/http_test_close.jinja"),
    ),
    (
        "ruby/http_request.jinja",
        include_str!("templates/ruby/http_request.jinja"),
    ),
    (
        "ruby/http_test_body.jinja",
        include_str!("templates/ruby/http_test_body.jinja"),
    ),
    (
        "ruby/http_101_skip.jinja",
        include_str!("templates/ruby/http_101_skip.jinja"),
    ),
    ("r/description.jinja", include_str!("templates/r/description.jinja")),
    ("r/assertion.jinja", include_str!("templates/r/assertion.jinja")),
    (
        "r/visitor_method.jinja",
        include_str!("templates/r/visitor_method.jinja"),
    ),
    ("r/test_runner.jinja", include_str!("templates/r/test_runner.jinja")),
    ("r/test_case.jinja", include_str!("templates/r/test_case.jinja")),
    ("r/test_file.jinja", include_str!("templates/r/test_file.jinja")),
    (
        "r/setup_fixtures.jinja",
        include_str!("templates/r/setup_fixtures.jinja"),
    ),
    (
        "r/synthetic_assertion.jinja",
        include_str!("templates/r/synthetic_assertion.jinja"),
    ),
    (
        "php/composer.json.jinja",
        include_str!("templates/php/composer.json.jinja"),
    ),
    ("php/phpunit.xml.jinja", include_str!("templates/php/phpunit.xml.jinja")),
    (
        "php/bootstrap.php.jinja",
        include_str!("templates/php/bootstrap.php.jinja"),
    ),
    ("php/assertion.jinja", include_str!("templates/php/assertion.jinja")),
    ("php/test_file.jinja", include_str!("templates/php/test_file.jinja")),
    ("php/test_method.jinja", include_str!("templates/php/test_method.jinja")),
    (
        "php/visitor_method.jinja",
        include_str!("templates/php/visitor_method.jinja"),
    ),
    (
        "php/http_test_open.jinja",
        include_str!("templates/php/http_test_open.jinja"),
    ),
    (
        "php/http_test_close.jinja",
        include_str!("templates/php/http_test_close.jinja"),
    ),
    (
        "php/http_request.jinja",
        include_str!("templates/php/http_request.jinja"),
    ),
    (
        "php/http_assertions.jinja",
        include_str!("templates/php/http_assertions.jinja"),
    ),
    (
        "php/http_test_skip_101.jinja",
        include_str!("templates/php/http_test_skip_101.jinja"),
    ),
    (
        "php/synthetic_assertion.jinja",
        include_str!("templates/php/synthetic_assertion.jinja"),
    ),
    ("csharp/csproj.jinja", include_str!("templates/csharp/csproj.jinja")),
    (
        "csharp/assertion.jinja",
        include_str!("templates/csharp/assertion.jinja"),
    ),
    (
        "csharp/visitor_method.jinja",
        include_str!("templates/csharp/visitor_method.jinja"),
    ),
    (
        "csharp/test_file.jinja",
        include_str!("templates/csharp/test_file.jinja"),
    ),
    (
        "csharp/test_method.jinja",
        include_str!("templates/csharp/test_method.jinja"),
    ),
    (
        "csharp/http_test_open.jinja",
        include_str!("templates/csharp/http_test_open.jinja"),
    ),
    (
        "csharp/http_test_close.jinja",
        include_str!("templates/csharp/http_test_close.jinja"),
    ),
    (
        "csharp/http_request.jinja",
        include_str!("templates/csharp/http_request.jinja"),
    ),
    (
        "csharp/http_test_body.jinja",
        include_str!("templates/csharp/http_test_body.jinja"),
    ),
    ("java/pom.xml.jinja", include_str!("templates/java/pom.xml.jinja")),
    ("java/test_file.jinja", include_str!("templates/java/test_file.jinja")),
    (
        "java/test_method.jinja",
        include_str!("templates/java/test_method.jinja"),
    ),
    ("java/assertion.jinja", include_str!("templates/java/assertion.jinja")),
    (
        "java/visitor_method.jinja",
        include_str!("templates/java/visitor_method.jinja"),
    ),
    (
        "java/http_test_open.jinja",
        include_str!("templates/java/http_test_open.jinja"),
    ),
    (
        "java/http_test_close.jinja",
        include_str!("templates/java/http_test_close.jinja"),
    ),
    (
        "java/http_request.jinja",
        include_str!("templates/java/http_request.jinja"),
    ),
    (
        "java/http_assertions.jinja",
        include_str!("templates/java/http_assertions.jinja"),
    ),
    (
        "java/http_test_skip_101.jinja",
        include_str!("templates/java/http_test_skip_101.jinja"),
    ),
    (
        "java/synthetic_assertion.jinja",
        include_str!("templates/java/synthetic_assertion.jinja"),
    ),
    (
        "typescript/package.json.jinja",
        include_str!("templates/typescript/package.json.jinja"),
    ),
    (
        "typescript/tsconfig.jinja",
        include_str!("templates/typescript/tsconfig.jinja"),
    ),
    (
        "typescript/vitest.config.ts.jinja",
        include_str!("templates/typescript/vitest.config.ts.jinja"),
    ),
    (
        "typescript/setup.ts.jinja",
        include_str!("templates/typescript/setup.ts.jinja"),
    ),
    (
        "typescript/globalSetup.ts.jinja",
        include_str!("templates/typescript/globalSetup.ts.jinja"),
    ),
    (
        "typescript/assertion.jinja",
        include_str!("templates/typescript/assertion.jinja"),
    ),
    (
        "typescript/synthetic_assertion.jinja",
        include_str!("templates/typescript/synthetic_assertion.jinja"),
    ),
    (
        "typescript/visitor_method.jinja",
        include_str!("templates/typescript/visitor_method.jinja"),
    ),
    (
        "typescript/test_file.jinja",
        include_str!("templates/typescript/test_file.jinja"),
    ),
    (
        "typescript/test_function.jinja",
        include_str!("templates/typescript/test_function.jinja"),
    ),
    (
        "typescript/helpers.jinja",
        include_str!("templates/typescript/helpers.jinja"),
    ),
    (
        "typescript/http_test.jinja",
        include_str!("templates/typescript/http_test.jinja"),
    ),
    (
        "typescript/cache_isolation_setup.jinja",
        include_str!("templates/typescript/cache_isolation_setup.jinja"),
    ),
    (
        "typescript/http_test_skip_101.jinja",
        include_str!("templates/typescript/http_test_skip_101.jinja"),
    ),
    (
        "python/http_test.jinja",
        include_str!("templates/python/http_test.jinja"),
    ),
    (
        "python/http_101_skip.jinja",
        include_str!("templates/python/http_101_skip.jinja"),
    ),
    (
        "wasm/package.json.jinja",
        include_str!("templates/wasm/package.json.jinja"),
    ),
    (
        "wasm/vitest.config.ts.jinja",
        include_str!("templates/wasm/vitest.config.ts.jinja"),
    ),
    (
        "wasm/globalSetup.ts.jinja",
        include_str!("templates/wasm/globalSetup.ts.jinja"),
    ),
    ("wasm/tsconfig.jinja", include_str!("templates/wasm/tsconfig.jinja")),
    ("wasm/assertion.jinja", include_str!("templates/wasm/assertion.jinja")),
    (
        "wasm/visitor_method.jinja",
        include_str!("templates/wasm/visitor_method.jinja"),
    ),
    (
        "zig/json_assertion.jinja",
        include_str!("templates/zig/json_assertion.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).expect("built-in template is valid");
    }
    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}"))
}
