import { Lexer } from 'chevrotain';
import { relationshipOptions } from '../../built-in-options/index.js';
import { BINARY_OPTION, NAME, UNARY_OPTION } from './shared-tokens.js';
import ValidationTokens from './validation-tokens.js';
import RelationshipTypeTokens from './relationship-type-tokens.js';
import AigcTypeTokens from './aigc-type-tokens.js';
import OptionTokens from './option-tokens.js';
import createTokenFromConfigCreator from './token-creator.js';
export const buildTokens = (tokens) => {
    const { applicationTokens, deploymentTokens } = tokens;
    const _tokens = {};
    const { BUILT_IN_ENTITY } = relationshipOptions;
    function createTokenFromConfig(config) {
        const newToken = createTokenFromConfigCreator(config);
        _tokens[config.name] = newToken;
        return newToken;
    }
    const BOOLEAN = createTokenFromConfig({
        name: 'BOOLEAN',
        pattern: Lexer.NA,
    });
    const CONFIG_KEY = applicationTokens.categoryToken;
    const DEPLOYMENT_KEY = deploymentTokens.categoryToken;
    createTokenFromConfig({
        name: 'WHITESPACE',
        pattern: /[\n\t\r \u2028\u2029]+/,
        group: Lexer.SKIPPED,
    });
    createTokenFromConfig({
        name: 'JAVADOC',
        pattern: /\/\*\*([\s\S]*?)\*\//,
    });
    createTokenFromConfig({
        name: 'BLOCK_COMMENT',
        pattern: /\/\*([\s\S]*?)\*\//,
        group: Lexer.SKIPPED,
    });
    createTokenFromConfig({ name: 'CONFIG', pattern: 'config' });
    createTokenFromConfig({ name: 'ENTITIES', pattern: 'entities' });
    applicationTokens.tokens.forEach(token => {
        _tokens[token.name] = token;
    });
    createTokenFromConfig({ name: 'APPLICATION', pattern: 'application' });
    createTokenFromConfig({
        name: 'SERVICE_DISCOVERY_TYPE',
        pattern: 'serviceDiscoveryType',
        categories: [CONFIG_KEY, DEPLOYMENT_KEY],
    });
    deploymentTokens.tokens.forEach(token => {
        _tokens[token.name] = token;
    });
    createTokenFromConfig({ name: 'DEPLOYMENT', pattern: 'deployment' });
    createTokenFromConfig({ name: 'TRUE', pattern: 'true', categories: [BOOLEAN] });
    createTokenFromConfig({ name: 'FALSE', pattern: 'false', categories: [BOOLEAN] });
    createTokenFromConfig({ name: 'ENTITY', pattern: 'entity' });
    createTokenFromConfig({ name: 'ENUM', pattern: 'enum' });
    createTokenFromConfig({ name: 'RELATIONSHIP', pattern: 'relationship' });
    createTokenFromConfig({ name: 'BUILT_IN_ENTITY', pattern: BUILT_IN_ENTITY });
    RelationshipTypeTokens.tokens.forEach(token => {
        _tokens[token.name] = token;
    });
    createTokenFromConfig({ name: 'AIGC', pattern: 'aigc' });
    AigcTypeTokens.tokens.forEach(token => {
        _tokens[token.name] = token;
    });
    createTokenFromConfig({ name: 'STAR', pattern: '*' });
    OptionTokens.tokens.forEach(token => {
        _tokens[token.name] = token;
    });
    ValidationTokens.tokens.forEach(token => {
        _tokens[token.name] = token;
    });
    createTokenFromConfig({ name: 'REGEX', pattern: /\/[^\n\r]*\// });
    createTokenFromConfig({ name: 'DECIMAL', pattern: /-?\d+\.\d+/ });
    createTokenFromConfig({ name: 'INTEGER', pattern: /-?\d+/ });
    createTokenFromConfig({ name: 'STRING', pattern: /"(?:[^"])*"/ });
    createTokenFromConfig({ name: 'LPAREN', pattern: '(' });
    createTokenFromConfig({ name: 'RPAREN', pattern: ')' });
    createTokenFromConfig({ name: 'LCURLY', pattern: '{' });
    createTokenFromConfig({ name: 'RCURLY', pattern: '}' });
    createTokenFromConfig({ name: 'LSQUARE', pattern: '[' });
    createTokenFromConfig({ name: 'RSQUARE', pattern: ']' });
    createTokenFromConfig({ name: 'COMMA', pattern: ',' });
    createTokenFromConfig({ name: 'COMMA_WITHOUT_NEWLINE', pattern: /,[^\n\r]/ });
    createTokenFromConfig({ name: 'EQUALS', pattern: '=' });
    createTokenFromConfig({ name: 'DOT', pattern: '.' });
    createTokenFromConfig({ name: 'TO', pattern: 'to' });
    createTokenFromConfig({ name: 'AT', pattern: '@' });
    const typedTokens = {
        UNARY_OPTION,
        BINARY_OPTION,
        NAME,
    };
    return {
        ..._tokens,
        ...typedTokens,
    };
};
export const createJDLLexer = (tokens) => new Lexer(Object.values(tokens), { ensureOptimizations: true });
