'use strict';
import _0x1bb941 from 'postgres';
import { drizzle } from 'drizzle-orm/postgres-js';
import { ilike, sql } from 'drizzle-orm';
import { isPgSelection, isSelectQuery, hasConfig } from '../guards/db-type-guards.js';
import { isTest } from '../../../fd-toolbox/lib/environments.js';
import { createError } from '../../../fd-toolbox/errors/errors.js';
import { logInfo } from '../../../fd-toolbox/server/logging/logger.js';
import { runDrizzleMigration, runDrizzleGeneration } from '../utils/run-migration-command.js';
import { dbErrorMessages, dbTransactions, getDrizzleDialectString, drizzleDialects, dbUrlSearchParams } from '../constants/db-constants.js';
import { booleanStringValues } from '../../../base-repo/constants/type-string-values.js';
import { ciDatabaseConstants } from '../../../infra/ci/constants/ci-constants.js';
import { ensurePathSeparatorAtTheStart } from '../../../fd-toolbox/paths/ensure.js';
import { first } from '../../../fd-toolbox/server/collections/single-funcs.js';
import { quoteSqlIdentifier, getSchemaTableNames } from '../utils/schema-table-names.js';

var __defProp=Object['defineProperty'],__name=(_0x362b8a,_0x305643)=>__defProp(_0x362b8a,'name',{'value':_0x305643,'configurable':!![]});class PostgresAdapter{static{__name(this,'PostgresAdapter');}#client;#db;#connectionString;#dbName;#schema;constructor(_0x3eccb6){this.#connectionString=_0x3eccb6,_0x3eccb6&&(this.#dbName=first(_0x3eccb6['slice'](_0x3eccb6['lastIndexOf']('/')+(0x27*0x7c+0x1409+-0x26ec))['split']('?')));}['init'](_0x426e46){this.#schema=_0x426e46;if(this.#client&&!isTest())return;const {connectionString:_0x4acb38}=this.#ensureConnection(),_0x13a705=this.#getSslConfig(_0x4acb38);this.#client=_0x1bb941(_0x4acb38,{'max':isTest()?-0x2*0xcb2+0x13a7+0x23*0x2a:void(-0x1*0x18c7+0x1e2d+-0x2b3*0x2),..._0x13a705}),this.#db=drizzle(this.#client,{'schema':_0x426e46});}['getDb'](){if(!this.#db)throw createError(dbErrorMessages['dbNotInitialized']);return this.#db;}['getClient'](){if(!this.#client)throw createError(dbErrorMessages['dbClientNotInitialized']);return this.#client;}async['beginUnsafeTransaction'](){await this['getClient']()['unsafe']('BEGIN');}async['rollbackUnsafeTransaction'](){await this['getClient']()['unsafe'](dbTransactions['rollback']);}['createDynamicSelect'](_0x3a705d,_0x4a61c7){const _0x2ce158=this['getDb'](),_0x56afd9=_0x4a61c7&&isPgSelection(_0x4a61c7)?_0x2ce158['select'](_0x4a61c7)['from'](_0x3a705d)['$dynamic']():_0x2ce158['select']()['from'](_0x3a705d)['$dynamic']();if(!isSelectQuery(_0x56afd9))throw createError(dbErrorMessages['drizzleUnexpectedObject']);return _0x56afd9;}['getQueryConfig'](_0x3160be){if(hasConfig(_0x3160be))return _0x3160be['config'];throw createError(dbErrorMessages['invalidObject']);}['getLikeExpression'](_0x57f05c,_0x3113d2){return ilike(_0x57f05c,_0x3113d2);}['getExtractDateExpression'](_0x546e44){return sql`DATE(${_0x546e44})`;}['leftJoin'](_0x5dfe9f,_0x58781,_0x564df0){return _0x5dfe9f['leftJoin'](_0x58781,_0x564df0);}['innerJoin'](_0x5ca5b0,_0x19c5e4,_0x5b9d98){return _0x5ca5b0['innerJoin'](_0x19c5e4,_0x5b9d98);}['orderBy'](_0x5afe85,..._0x58f8e4){return _0x5afe85['orderBy'](..._0x58f8e4);}['groupBy'](_0x2f3bf7,..._0x5e6727){return _0x2f3bf7['groupBy'](..._0x5e6727);}['having'](_0x5d398a,_0x10d725){return _0x5d398a['having'](_0x10d725);}['limit'](_0x14ec29,_0xd829aa){return _0x14ec29['limit'](_0xd829aa);}['offset'](_0x365b59,_0x297f04){return _0x365b59['offset'](_0x297f04);}['where'](_0x228427,_0x432f30){if(!_0x432f30)return _0x228427;return _0x228427['where'](_0x432f30);}['insert'](_0x5f1cdf){return this['getDb']()['insert'](_0x5f1cdf);}['update'](_0x4a271b){return this['getDb']()['update'](_0x4a271b);}['delete'](_0x55c62a){return this['getDb']()['delete'](_0x55c62a);}async['createDatabaseIfNotExists'](){const {dbName:_0x512a7c}=this.#ensureConnection(),_0x779cca=this.#getClientForDefaultPostgresDatabase();try{const _0x421068=await _0x779cca['unsafe']('SELECT\x201\x20FROM\x20pg_database\x20WHERE\x20datname\x20=\x20\x27'+_0x512a7c+'\x27');_0x421068['length']===-0x17d6+-0xe6*-0xa+-0xeda*-0x1?(await _0x779cca['unsafe']('CREATE\x20DATABASE\x20\x22'+_0x512a7c+'\x22'),logInfo('Database\x20'+_0x512a7c+'\x20created.')):logInfo('Database\x20'+_0x512a7c+'\x20already\x20exists.'),await this.#verifyDatabaseReachable();}catch(_0x48adf2){throw createError('Error\x20creating\x20database\x20'+_0x512a7c+':',_0x48adf2);}finally{await _0x779cca['end']();}}async #verifyDatabaseReachable(){const {connectionString:_0x87269c,dbName:_0x584b2d}=this.#ensureConnection(),_0x2e0456=-0xf71+-0x2*-0x51b+-0x60*-0xe,_0x28dbe8=0x178d+0xf84+-0x1f41;logInfo('Verifying\x20reachability\x20for\x20database:\x20'+_0x584b2d+'...');for(let _0x5efd8b=0xd15+-0x7*-0xa3+-0x118a;_0x5efd8b<_0x2e0456;_0x5efd8b++){const _0x2e63a0=_0x1bb941(_0x87269c,{'max':0x1,'connect_timeout':0x5,...this.#getSslConfig(_0x87269c)});try{await _0x2e63a0`SELECT 1`,logInfo('Database\x20'+_0x584b2d+'\x20is\x20ready.'),await _0x2e63a0['end']();return;}catch(_0x4f3228){logInfo('Database\x20'+_0x584b2d+'\x20not\x20reachable\x20yet\x20(attempt\x20'+(_0x5efd8b+(0x16f5+0x1*0x1d8e+-0x4c6*0xb))+'/'+_0x2e0456+').\x20Waiting\x20'+_0x28dbe8+'ms...'),await _0x2e63a0['end']();if(_0x5efd8b===_0x2e0456-(-0x1a3c*-0x1+-0x1*-0x313+-0x1d4e))throw createError('Database\x20'+_0x584b2d+'\x20failed\x20to\x20become\x20reachable\x20after\x20'+_0x2e0456+'\x20attempts',_0x4f3228);await new Promise(_0x273895=>setTimeout(_0x273895,_0x28dbe8));}}}async['dropDatabase'](){const {dbName:_0x1966ff}=this.#ensureConnection(),_0xdc7957=this.#getClientForDefaultPostgresDatabase();try{const _0x50be77=await _0xdc7957['unsafe']('SELECT\x201\x20FROM\x20pg_database\x20WHERE\x20datname\x20=\x20\x27'+_0x1966ff+'\x27');if(_0x50be77['length']>-0x2*-0xdfa+0x373+-0x1f67*0x1){this.#client&&(await this.#client['end'](),this.#client=void(0x1957*0x1+-0x79*0x27+-0xd*0x88),this.#db=void(0x2b2+0x209b*0x1+-0x234d));try{await _0xdc7957['unsafe']('\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20SELECT\x20pg_terminate_backend(pid)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20FROM\x20pg_stat_activity\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20WHERE\x20datname\x20=\x20\x27'+_0x1966ff+'\x27\x20AND\x20pid\x20<>\x20pg_backend_pid();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20');}catch(_0x31cb5b){logInfo('Warning:\x20Could\x20not\x20terminate\x20existing\x20database\x20sessions\x20for\x20'+_0x1966ff+'.\x20This\x20might\x20be\x20expected\x20in\x20some\x20environments\x20(e.g.\x20Vercel\x20Neon).\x20Error:\x20'+_0x31cb5b);}await _0xdc7957['unsafe']('DROP\x20DATABASE\x20\x22'+_0x1966ff+'\x22'),logInfo('Database\x20'+_0x1966ff+'\x20deleted.');}else logInfo('Database\x20'+_0x1966ff+'\x20not\x20found.');}catch(_0x5ae920){throw createError('Error\x20dropping\x20database\x20'+_0x1966ff,_0x5ae920);}finally{await _0xdc7957['end']();}}async['emptyAllTables'](){const _0x2e4ad9=this.#getSchemaTableNames();if(_0x2e4ad9['length']===0x21c5*0x1+0x2*0x119c+0x16ff*-0x3)return;const _0x368039=_0x2e4ad9['map'](quoteSqlIdentifier)['join'](',\x20');await this['getClient']()['unsafe']('TRUNCATE\x20TABLE\x20'+_0x368039+'\x20RESTART\x20IDENTITY\x20CASCADE');}async['runMigrations'](){const {connectionString:_0x5bab00}=this.#ensureConnection();await this['createDatabaseIfNotExists'](),await runDrizzleMigration({'dialect':getDrizzleDialectString(drizzleDialects['postgresql']),'dbUrl':_0x5bab00});}async['generateMigrations'](_0xa41f7e){this.#ensureConnection(),await this['createDatabaseIfNotExists'](),await runDrizzleGeneration(_0xa41f7e);}#getClientForDefaultPostgresDatabase(){const _0x368a39=new URL(this.#ensureConnection()['connectionString']);return _0x368a39['pathname']=ensurePathSeparatorAtTheStart(ciDatabaseConstants['user']),_0x1bb941(_0x368a39['toString'](),this.#getSslConfig(_0x368a39['toString']()));}#getSchemaTableNames(){if(!this.#schema)throw createError(dbErrorMessages['dbNotInitialized']);return getSchemaTableNames(this.#schema);}#ensureConnection(){if(!this.#connectionString||!this.#dbName)throw createError(dbErrorMessages['dbConnectionStringNotProvided']);return {'connectionString':this.#connectionString,'dbName':this.#dbName};}#getSslConfig(_0x130a03){const _0x3ce6f5=new URL(_0x130a03);return _0x3ce6f5['searchParams']['get']('sslmode')===dbUrlSearchParams['require']||_0x3ce6f5['searchParams']['get']('ssl')===booleanStringValues['true']?{'ssl':!![]}:{};}}

export { PostgresAdapter };
