// codragraph/src/core/ingestion/variable-extractors/configs/c-cpp.ts
import { SupportedLanguages } from '../../../../_shared/index.js';
import { hasKeyword } from '../../field-extractors/configs/helpers.js';
import { extractSimpleTypeName } from '../../type-extractors/shared.js';
/**
 * C/C++ variable extraction config.
 *
 * Handles global/namespace-scoped variable declarations:
 * - `int x = 5;`
 * - `const int MAX = 100;`
 * - `static int counter = 0;`
 * - `constexpr int SIZE = 10;` (C++)
 * - `extern int shared;`
 *
 * tree-sitter-c/cpp uses declaration for variable declarations.
 */
function extractCVarName(node) {
    // declaration → declarator (init_declarator or identifier)
    for (let i = 0; i < node.namedChildCount; i++) {
        const child = node.namedChild(i);
        if (child?.type === 'init_declarator') {
            const declarator = child.childForFieldName('declarator');
            if (declarator?.type === 'identifier')
                return declarator.text;
            if (declarator?.type === 'pointer_declarator') {
                const inner = declarator.namedChildren.find((c) => c.type === 'identifier');
                return inner?.text;
            }
        }
        if (child?.type === 'identifier')
            return child.text;
    }
    return undefined;
}
function extractCVarType(node) {
    const typeNode = node.childForFieldName('type');
    if (typeNode)
        return extractSimpleTypeName(typeNode) ?? typeNode.text?.trim();
    // Fallback: first primitive_type or type_identifier child
    for (let i = 0; i < node.namedChildCount; i++) {
        const child = node.namedChild(i);
        if (child?.type === 'primitive_type' ||
            child?.type === 'type_identifier' ||
            child?.type === 'sized_type_specifier') {
            return child.text?.trim();
        }
    }
    return undefined;
}
const shared = {
    constNodeTypes: [],
    staticNodeTypes: [],
    variableNodeTypes: ['declaration'],
    extractName: extractCVarName,
    extractType: extractCVarType,
    extractVisibility(node) {
        // C/C++ visibility is file-scoped by default (static = file-private)
        if (hasKeyword(node, 'static'))
            return 'private';
        if (hasKeyword(node, 'extern'))
            return 'public';
        return 'public';
    },
    isConst(node) {
        return hasKeyword(node, 'const') || hasKeyword(node, 'constexpr');
    },
    isStatic(node) {
        return hasKeyword(node, 'static');
    },
    isMutable(node) {
        return !hasKeyword(node, 'const') && !hasKeyword(node, 'constexpr');
    },
};
export const cVariableConfig = {
    ...shared,
    language: SupportedLanguages.C,
};
export const cppVariableConfig = {
    ...shared,
    language: SupportedLanguages.CPlusPlus,
};
