/**
 * tableStructureRegistry.js — lazy-loading registry for database table structures.
 *
 * Each table has a dedicated structure file under ./tableStructures/<CODE>.js
 * that is loaded on first access via dynamic import(). Only the tables relevant
 * to a given script are ever loaded — loading all 100+ definitions upfront would
 * be wasteful when the caller typically works with only one or two tables.
 *
 * Usage:
 *   import { getTableStructure, isKnownTableStructure } from './tableStructureRegistry.js';
 *
 *   if (isKnownTableStructure("CD")) {
 *     const cd = await getTableStructure("CD");
 *     // cd.indexes, cd.fields, cd.recordLength …
 *   }
 *
 * To add a new table:
 *   1. Create  core/src/builtins/tableStructures/<CODE>.js  (export default tableObject)
 *   2. Add the code to  KNOWN_TABLE_CODES  below.
 */

/**
 * Table codes that have a corresponding structure file.
 * When a new tableStructures/<CODE>.js file is added, register it here.
 * @type {ReadonlySet<string>}
 */
const KNOWN_TABLE_CODES = new Set(["CD", "MD", "RA"]);

/**
 * Cache of already-loaded table structures, keyed by table code.
 * @type {Map<string, Object>}
 */
const _cache = new Map();

/**
 * Returns true if a structure file is registered for the given table code.
 * This is a synchronous check — no I/O is performed.
 *
 * @param {string} code - 2-character table code (e.g. "CD", "MD").
 * @returns {boolean}
 */
function isKnownTableStructure(code) {
    return KNOWN_TABLE_CODES.has(code);
}

/**
 * Returns the full structure object for a table, loading and caching it on first
 * access.  Returns null if no structure file is registered for the code.
 *
 * The returned object has the shape:
 * {
 *   code:         string,
 *   name:         string,
 *   recordLength: number,
 *   helpRegistry: string,
 *   indexes:      Array<{ name, modifiable, duplicates, segments: Array<{position, field, type, length}> }>,
 *   fields:       { [lowercaseFieldName]: { canonical, type, tableCode } }
 * }
 *
 * @param {string} code - 2-character table code.
 * @returns {Promise<Object|null>}
 */
async function getTableStructure(code) {
    if (!KNOWN_TABLE_CODES.has(code)) {
        return null;
    }
    if (_cache.has(code)) {
        return _cache.get(code);
    }
    const { default: structure } = await import(`./tableStructures/${code}.js`);
    _cache.set(code, structure);
    return structure;
}

/**
 * Returns the structure for a table if it has already been loaded into the cache,
 * otherwise returns undefined.
 *
 * This is a synchronous accessor intended for callers that have already awaited
 * at least one call to getTableStructure() for this code.
 *
 * @param {string} code - 2-character table code.
 * @returns {Object|undefined}
 */
function getLoadedTableStructure(code) {
    return _cache.get(code);
}

export { isKnownTableStructure, getTableStructure, getLoadedTableStructure };
