{{#if has_hash_map}}
use rustc_hash::FxHashMap;
{{/if}}
{{#if has_hash_set}}
use rustc_hash::FxHashSet;
{{/if}}
{{#if rule_config}}
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
{{/if}}

use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{
    context::LintContext,
    fixer::{RuleFix, RuleFixer},
    {{#if rule_config}}rule::{DefaultRuleConfig, Rule},{{else}}rule::Rule,{{/if}}
    AstNode,
};

fn {{snake_rule_name}}_diagnostic(span: Span) -> OxcDiagnostic {
    // See <https://oxc.rs/docs/contribute/linter/adding-rules.html#diagnostics> for details
    OxcDiagnostic::warn("Should be an imperative statement about what is wrong.")
        .with_help("Should be a command-like statement that tells the user how to fix the issue.")
        .with_label(span)
}

{{rule_config}}

#[derive(Debug, Default, Clone{{#if rule_config_tuple}}, Deserialize, Serialize, JsonSchema{{/if}})]
pub struct {{pascal_rule_name}}{{#if rule_config_tuple}}{{rule_config_tuple}}{{/if}};

// See <https://github.com/oxc-project/oxc/issues/6050> for documentation details.
declare_oxc_lint!(
    /// ### What it does
    ///
    /// FIXME: Briefly describe the rule's purpose.
    ///
    /// ### Why is this bad?
    ///
    /// FIXME: Explain why violating this rule is problematic.
    ///
    /// ### Examples
    ///
    /// Examples of **incorrect** code for this rule:
    /// ```{{language}}
    /// FIXME: Add at least one example of code that violates the rule.
    /// ```
    ///
    /// Examples of **correct** code for this rule:
    /// ```{{language}}
    /// FIXME: Add at least one example of code that is allowed with the rule.
    /// ```
    {{pascal_rule_name}},
    {{mod_name}},
    nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style`
             // See <https://oxc.rs/docs/contribute/linter.html#rule-category> for details
    pending, // TODO: describe fix capabilities. Remove or set to `none` if no fix can be done,
             // keep at 'pending' if you think one could be added but don't know how.
             // Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion'
{{#if rule_config}}
    config = {{pascal_rule_name}},
{{/if}}
    version = "next",
    short_description = "FIXME: One-sentence description of the rule.",
);

impl Rule for {{pascal_rule_name}} {
{{#if rule_config}}
    fn from_configuration(value: serde_json::Value) -> Result<Self, serde_json::error::Error> {
        serde_json::from_value::<DefaultRuleConfig<Self>>(value).map(DefaultRuleConfig::into_inner)
    }

{{/if}}
    fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {

    }
}

#[test]
fn test() {
    {{#if has_filename}}
    use std::path::PathBuf;

    {{/if}}
    use crate::tester::Tester;

    let pass = vec![
        {{pass_cases}}
    ];

    let fail = vec![
        {{fail_cases}}
    ];

    {{#if fix_cases}}
    let fix = vec![
        {{fix_cases}}
    ];

    Tester::new({{pascal_rule_name}}::NAME, {{pascal_rule_name}}::PLUGIN, pass, fail).expect_fix(fix).test_and_snapshot();
    {{else}}
    Tester::new({{pascal_rule_name}}::NAME, {{pascal_rule_name}}::PLUGIN, pass, fail).test_and_snapshot();
    {{/if}}
}
