import { ReservedKeywords } from './postgresql.js';
import { DomainPropertyKind } from '../../models/kinds.js';
/**
 * Validates the property name. This includes associations.
 *
 * @remarks
 * - A property must have a name defined.
 * - The name has to follow the same rules as the names in a PostgreSQL database.
 *   - Column names can only contain letters (a-z, A-Z), numbers (0-9), and underscores (_).
 *   - The name must start with a letter (a-z, A-Z) or an underscore (_).
 *   - PostgreSQL limits column names to a maximum of 59 characters.
 *   - (our rule) Column names are case insensitive.
 *   - (recommendation) Column names should be in lower case.
 *
 * @param property The property to validate
 */
export function validatePropertyName(property) {
    const results = [];
    const label = property.info.getLabel();
    const parentEntity = property.getParentInstance();
    const type = property.kind === DomainPropertyKind ? 'property' : 'association';
    if (!property.info.name) {
        const message = `The "${label}" ${type} has no name.`;
        const help = `The ${type} must have a name.`;
        results.push({
            field: 'name',
            rule: 'required',
            message,
            help,
            severity: 'error',
            key: property.key,
            kind: property.kind,
            parent: parentEntity.key,
        });
        return results;
    }
    const name = property.info.name;
    if (name.length < 2) {
        const message = `The "${label}" ${type} name is too short.`;
        const help = `The name must be at least 2 characters long.`;
        results.push({
            field: 'name',
            rule: 'length',
            message,
            help,
            severity: 'error',
            key: property.key,
            kind: property.kind,
            parent: parentEntity.key,
        });
    }
    if (name.length > 59) {
        const message = `The "${label}" ${type} name is too long.`;
        const help = `The name must be at most 59 characters long.`;
        results.push({
            field: 'name',
            rule: 'length',
            message,
            help,
            severity: 'error',
            key: property.key,
            kind: property.kind,
            parent: parentEntity.key,
        });
    }
    if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
        const message = `The "${label}" ${type} name is invalid.`;
        const help = `The name must start with a letter (a-z) or underscore (_). Subsequent characters can be letters, digits (0-9), or underscores (_).`;
        results.push({
            field: 'name',
            rule: 'format',
            message,
            help,
            severity: 'error',
            key: property.key,
            kind: property.kind,
            parent: parentEntity.key,
        });
    }
    if (/^[A-Z]/.test(name)) {
        const message = `The "${label}" ${type} name is not in snake case.`;
        const help = `The name should be in snake case (lowercase letters and underscores).`;
        results.push({
            field: 'name',
            rule: 'snake_case',
            message,
            help,
            severity: 'info',
            key: property.key,
            kind: property.kind,
            parent: parentEntity.key,
        });
    }
    if (ReservedKeywords.has(name.toUpperCase())) {
        const message = `The "${label}" ${type} name is a reserved keyword.`;
        const help = `The name should not be a reserved keyword.`;
        results.push({
            field: 'name',
            rule: 'reserved',
            message,
            help,
            severity: 'error',
            key: property.key,
            kind: property.kind,
            parent: parentEntity.key,
        });
    }
    return results;
}
//# sourceMappingURL=rules.js.map