import { getTableName } from "drizzle-orm";
import { SybasePool } from "./connection.js";
import { SybaseDialect, escapeName } from "./dialect.js";
import { SybaseSelectBuilder, SybaseInsertBuilder, SybaseUpdateBuilder, SybaseDeleteBuilder } from "./query-builders/index.js";
import { SybaseSession } from "./session.js";
// ---------------------------------------------------------------------------
// Implementation
// ---------------------------------------------------------------------------
export const createSybaseDrizzle = (config) => {
    const dialect = new SybaseDialect();
    const pool = new SybasePool(config);
    const session = new SybaseSession(pool);
    const resolveFields = (fields) => {
        if (!fields) {
            return [{ expression: "*" }];
        }
        return Object.entries(fields).map(([alias, field]) => {
            if (field && field.name && field.table) {
                const tableName = getTableName(field.table);
                return {
                    expression: `${escapeName(tableName)}.${escapeName(field.name)}`,
                    alias
                };
            }
            if (field && typeof field.getSQL === "function") {
                const sqlStr = dialect.sqlToQuery(field.getSQL());
                return { expression: sqlStr, alias };
            }
            if (field && typeof field.toQuery === "function") {
                return { expression: dialect.sqlToQuery(field), alias };
            }
            if (typeof field === "string") {
                return { expression: field, alias };
            }
            throw new Error(`Cannot resolve field "${alias}": unsupported value type. ` +
                `Expected a column reference, SQL expression, or string.`);
        });
    };
    return {
        select(fields) {
            return new SybaseSelectBuilder(dialect, session, resolveFields(fields));
        },
        insert(table) {
            return new SybaseInsertBuilder(table, dialect, session);
        },
        update(table) {
            return new SybaseUpdateBuilder(table, dialect, session);
        },
        delete(table) {
            return new SybaseDeleteBuilder(table, dialect, session);
        },
        async execute(query) {
            const rawSql = dialect.sqlToQuery(query);
            return session.execute(rawSql);
        },
        async exec(query) {
            return this.execute(query);
        },
        async executeRaw(rawSql) {
            return session.execute(rawSql);
        },
        async transaction(fn, options) {
            return session.transaction(async (txSession) => {
                const tx = {
                    select(fields) {
                        return new SybaseSelectBuilder(dialect, txSession, resolveFields(fields));
                    },
                    insert(table) {
                        return new SybaseInsertBuilder(table, dialect, txSession);
                    },
                    update(table) {
                        return new SybaseUpdateBuilder(table, dialect, txSession);
                    },
                    delete(table) {
                        return new SybaseDeleteBuilder(table, dialect, txSession);
                    },
                    async execute(query) {
                        const rawSql = dialect.sqlToQuery(query);
                        return txSession.execute(rawSql);
                    },
                    async exec(query) {
                        return this.execute(query);
                    },
                    async executeRaw(rawSql) {
                        return txSession.execute(rawSql);
                    }
                };
                return fn(tx);
            }, options);
        },
        async close() {
            await pool.close();
        },
        async drain(timeoutMs) {
            await pool.drain(timeoutMs);
        },
        get pool() {
            return {
                get size() {
                    return pool.size;
                },
                get active() {
                    return pool.active;
                },
                get idle() {
                    return pool.idle;
                },
                get waiting() {
                    return pool.waiting;
                },
                get isDraining() {
                    return pool.isDraining;
                },
                get isClosed() {
                    return pool.isClosed;
                },
                get metrics() {
                    return pool.metrics;
                }
            };
        }
    };
};
//# sourceMappingURL=db.js.map