import { arrayLast, setHas } from "ts-extras";
import { ruleCreator } from "../_internal/rule-creator.js";
import { createReplacementRuleInfo, withDeprecatedRuleLifecycle, } from "../_internal/rule-deprecation.js";
const defaultKinds = [
    "arrow-function",
    "class",
    "function",
    "method",
    "type",
];
const hasJSDocComment = (sourceCode, node) => {
    const comments = sourceCode.getCommentsBefore(node);
    const comment = arrayLast(comments);
    return comment?.type === "Block" && comment.value.startsWith("*");
};
const reportMissingJSDoc = (context, node) => {
    if (hasJSDocComment(context.sourceCode, node)) {
        return;
    }
    context.report({
        messageId: "missing",
        node,
    });
};
/**
 * Require JSDoc comments for configured declaration kinds.
 */
const rule = ruleCreator({
    create: (context, [options]) => {
        const kinds = new Set(options.kinds ?? defaultKinds);
        return {
            ClassDeclaration: (node) => {
                if (!setHas(kinds, "class") || node.id === null) {
                    return;
                }
                reportMissingJSDoc(context, node);
            },
            FunctionDeclaration: (node) => {
                if (!setHas(kinds, "function") || node.id === null) {
                    return;
                }
                reportMissingJSDoc(context, node);
            },
            MethodDefinition: (node) => {
                if (!setHas(kinds, "method") ||
                    node.kind === "constructor" ||
                    node.key.type !== "Identifier") {
                    return;
                }
                reportMissingJSDoc(context, node);
            },
            "TSTypeAliasDeclaration, TSInterfaceDeclaration": (node) => {
                if (!setHas(kinds, "type")) {
                    return;
                }
                if (node.type === "TSInterfaceDeclaration" ||
                    node.type === "TSTypeAliasDeclaration") {
                    reportMissingJSDoc(context, node);
                }
            },
            VariableDeclarator: (node) => {
                if (!setHas(kinds, "arrow-function") ||
                    node.id.type !== "Identifier" ||
                    node.init?.type !== "ArrowFunctionExpression" ||
                    node.parent.type !== "VariableDeclaration" ||
                    node.parent.kind !== "const") {
                    return;
                }
                reportMissingJSDoc(context, node.parent);
            },
        };
    },
    defaultOptions: [{ kinds: defaultKinds }],
    meta: {
        defaultOptions: [{ kinds: defaultKinds }],
        deprecated: true,
        docs: {
            deprecated: true,
            description: "require JSDoc comments for configured declaration kinds.",
            frozen: true,
            recommended: false,
            url: "https://nick2bad4u.github.io/eslint-plugin-etc-misc/docs/rules/require-jsdoc",
        },
        hasSuggestions: false,
        messages: {
            missing: "Missing JSDoc comment.",
        },
        schema: [
            {
                additionalProperties: false,
                description: "Configuration for declaration kinds that require JSDoc.",
                properties: {
                    kinds: {
                        description: "Declaration kinds that must have a leading JSDoc comment.",
                        items: {
                            enum: [...defaultKinds],
                            type: "string",
                        },
                        type: "array",
                    },
                },
                type: "object",
            },
        ],
        type: "suggestion",
    },
    name: "require-jsdoc",
});
/**
 * Wrapper rule with explicit lifecycle metadata and replacement mapping.
 */
const deprecatedRule = withDeprecatedRuleLifecycle(rule, {
    message: "Deprecated in favor of jsdoc/require-jsdoc.",
    replacedBy: [
        createReplacementRuleInfo({
            plugin: {
                name: "jsdoc",
                url: "https://github.com/gajus/eslint-plugin-jsdoc",
            },
            rule: {
                name: "require-jsdoc",
                url: "https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-jsdoc.md",
            },
        }),
    ],
    ruleId: "require-jsdoc",
});
export default deprecatedRule;
//# sourceMappingURL=require-jsdoc.js.map