/**
 * Language constants and keywords for Acurity Architect.
 */

const ACURITY_KEYWORDS = new Set([
    "AND", "OR", "NOT", "TRUE", "FALSE",
    "IF", "ENDIF", "ELSE",
    "DO", "ENDDO", "WHILE", "FOR", "FOREVER", "UNTIL", "BREAK", "CONTINUE", "COUNT",
    "CASE", "ENDCASE", "WHEN", "OTHERWISE", "VALUE", "OF",
    "FUNCTION", "ENDFUNCTION", "RETURN",
    "MACRO",
    "VAR", "SET", "OPTION", "HASH-ON", "HASH-OFF", "NEWINTERPRETER",
    "INCLUDE", "INCLUDEONCE", "INCLUDETEST", "REQUIRE",
    "EXIT", "END-OF-CODE"
]);

const ACURITY_TYPES = new Set([
    "STRING", "SHORT", "LONG", "DOUBLE", "BOOLEAN", "DATE", "TIME", "INTEGER", "BIGINT"
]);

const DATABASE_HANDLE_TYPE_MAP = {
    z: "STRING",    // String
    f: "DOUBLE",    // Floating-point (Double)
    s: "SHORT",     // Short integer
    l: "LONG"       // Long integer
};

const LANGUAGE_ID = "acurity";
const MACRO_TRIGGER_CHARACTER = "_";

/**
 * Checks if a name is a valid database handle reference.
 * Database handles conventionally follow: h + 2-letter table code + 1-letter type + _ + field name
 * but for validation purposes we treat any token with a single lowercase 'h' prefix
 * (i.e., first char 'h' and second char not lowercase) as a database field reference.
 * Example: hRLz_Fund (h=handle, RL=Report Details table, z=STRING type, Fund=field name)
 * @param {string} name - The name to check
 * @returns {Object|null} - { isValid: boolean, type: string } or null
 */
function isDatabaseHandle(name) {
    if (!name || name.length === 0 || name[0] !== "h") {
        return null;
    }

    // Single lowercase 'h' prefix indicates a database field token.
    // If followed by another lowercase letter, this is not a single-char prefix.
    if (name.length > 1 && name[1] >= "a" && name[1] <= "z") {
        return null;
    }

    const pattern = /^h([a-z]{2})([zfsl])_(.+)$/i;
    const match = name.match(pattern);

    // Return best-effort metadata even when strict pattern is not matched.
    if (!match) {
        return {
            isValid: true,
            name,
            tableCode: null,
            typeChar: null,
            type: "UNKNOWN",
            fieldName: null
        };
    }
    
    const typeChar = match[2].toLowerCase();
    const type = DATABASE_HANDLE_TYPE_MAP[typeChar];
    
    return {
        isValid: true,
        name: name,
        tableCode: match[1],
        typeChar: typeChar,
        type: type || "UNKNOWN",
        fieldName: match[3]
    };
}

export {
    ACURITY_KEYWORDS,
    ACURITY_TYPES,
    LANGUAGE_ID,
    MACRO_TRIGGER_CHARACTER,
    isDatabaseHandle,
    DATABASE_HANDLE_TYPE_MAP
};
