import { ErrorFactory } from '../exceptions/ZintrustError.js';
import * as path from '../node-singletons/path.js';
import { pathToFileURL } from '../node-singletons/url.js';
function isFunction(value) {
    return typeof value === 'function';
}
function normalizeHandler(fn, label) {
    if (!isFunction(fn)) {
        throw ErrorFactory.createValidationError(`Invalid migration export: expected function for ${label}`);
    }
    return async (db) => {
        // Support both (db) => Promise<void> and () => Promise<void>.
        if (fn.length <= 0) {
            await Promise.resolve(fn());
            return;
        }
        await Promise.resolve(fn(db));
    };
}
export const MigrationLoader = Object.freeze({
    async load(filePath) {
        const url = pathToFileURL(filePath).href;
        const raw = (await import(url));
        // Some tooling/transpilation paths wrap exports under `default`.
        // Prefer direct named exports, but fall back to default export if present.
        const mod = (raw ?? {});
        const fallback = (mod.default ?? {});
        const up = mod.migration?.up ?? mod.up ?? fallback.migration?.up ?? fallback.up;
        const down = mod.migration?.down ?? mod.down ?? fallback.migration?.down ?? fallback.down;
        if (up === undefined) {
            throw ErrorFactory.createValidationError(`Migration '${filePath}' is missing an 'up' export`);
        }
        if (down === undefined) {
            throw ErrorFactory.createValidationError(`Migration '${filePath}' is missing a 'down' export`);
        }
        return {
            name: path.basename(filePath, path.extname(filePath)),
            filePath,
            up: normalizeHandler(up, 'up'),
            down: normalizeHandler(down, 'down'),
        };
    },
});
