"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const typescript_1 = __importDefault(require("typescript"));
const fs_1 = __importDefault(require("fs"));
const printer = typescript_1.default.createPrinter();
const prepareFabricFile = (folder) => {
    const staticImports = [
        typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(undefined, typescript_1.default.createNamespaceImport(typescript_1.default.createIdentifier('drizzle'))), typescript_1.default.createStringLiteral('drizzle-orm')),
        typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(typescript_1.default.createIdentifier('Session'), undefined), typescript_1.default.createStringLiteral('drizzle-orm/db/session')),
        typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(typescript_1.default.createIdentifier('MigrationSerializer'), undefined), typescript_1.default.createStringLiteral('drizzle-orm/serializer/serializer')),
        typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(typescript_1.default.createIdentifier("Enum"), undefined), typescript_1.default.createStringLiteral("drizzle-orm/types/type")),
        typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(undefined, typescript_1.default.createNamespaceImport(typescript_1.default.createIdentifier('pg'))), typescript_1.default.createStringLiteral('pg')),
    ];
    const dynamicImports = [];
    const filenames = fs_1.default.readdirSync(folder);
    for (let i = 0; i < filenames.length; i++) {
        const filename = filenames[i];
        const importPath = `${folder}/${filename.split(".")[0]}`;
        dynamicImports.push(typescript_1.default.createImportDeclaration(undefined, undefined, typescript_1.default.createImportClause(undefined, typescript_1.default.createNamespaceImport(typescript_1.default.createIdentifier(`i${i}`))), typescript_1.default.createStringLiteral(importPath)));
    }
    const variablesStatements = [
        typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
            typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier("db"), undefined, typescript_1.default.createNew(typescript_1.default.createIdentifier("drizzle.DB"), undefined, [
                typescript_1.default.createNew(typescript_1.default.createIdentifier("Session"), undefined, [typescript_1.default.createNew(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier('pg'), typescript_1.default.createIdentifier('Pool')), undefined, [])]),
            ])),
        ], typescript_1.default.NodeFlags.Const)),
        typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
            typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier("serializer"), undefined, typescript_1.default.createNew(typescript_1.default.createIdentifier("MigrationSerializer"), undefined, [])),
        ], typescript_1.default.NodeFlags.Const)),
    ];
    const blockStatements = [];
    // const tables: AbstractTable<any> = []
    blockStatements.push(typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
        typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier('tables'), typescript_1.default.createArrayTypeNode(typescript_1.default.createTypeReferenceNode(typescript_1.default.createQualifiedName(typescript_1.default.createIdentifier('drizzle'), typescript_1.default.createIdentifier('AbstractTable')), [typescript_1.default.createKeywordTypeNode(typescript_1.default.SyntaxKind.AnyKeyword)])), typescript_1.default.createArrayLiteral([], false)),
    ], typescript_1.default.NodeFlags.Const)));
    // const enums: Enum<any>[] = []
    blockStatements.push(typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
        typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier('enums'), typescript_1.default.createArrayTypeNode(typescript_1.default.createTypeReferenceNode(typescript_1.default.createIdentifier('Enum'), [typescript_1.default.createKeywordTypeNode(typescript_1.default.SyntaxKind.AnyKeyword)])), typescript_1.default.createArrayLiteral([], false))
    ], typescript_1.default.NodeFlags.Const)));
    for (let i = 0; i < filenames.length; i++) {
        // const t1 = (new i1.default(db) as unknown as AbstractTable<any>);
        // tables.push(t1)
        // const i1values = Object.values(i1)
        const valuesDeclaration = typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
            typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier(`i${i}values`), undefined, typescript_1.default.createCall(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier('Object'), typescript_1.default.createIdentifier('values')), undefined, [typescript_1.default.createIdentifier('i' + i)]))
        ], typescript_1.default.NodeFlags.Const));
        blockStatements.push(valuesDeclaration);
        //  i1values.forEach((t) => {
        //   if (t instanceof Enum) {
        //     enums.push(t);
        //     return
        //   }
        //   if (typeof t === 'function' && t.prototype && t.prototype.constructor) {
        //     const instance = new t(db)
        //     if (instance instanceof AbstractTable) {
        //       tables.push(instance as unknown as AbstractTable<any>)
        //     }
        //   }
        // });
        const iterationWithTypeChecks = typescript_1.default.createExpressionStatement(typescript_1.default.createCall(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier(`i${i}values`), typescript_1.default.createIdentifier('forEach')), undefined, [
            typescript_1.default.createArrowFunction(undefined, undefined, [
                typescript_1.default.createParameter(undefined, undefined, undefined, typescript_1.default.createIdentifier('t'), undefined, undefined, undefined)
            ], undefined, typescript_1.default.createToken(typescript_1.default.SyntaxKind.EqualsGreaterThanToken), typescript_1.default.createBlock([
                typescript_1.default.createIf(typescript_1.default.createBinary(typescript_1.default.createIdentifier('t'), typescript_1.default.SyntaxKind.InstanceOfKeyword, typescript_1.default.createIdentifier('Enum')), typescript_1.default.createBlock([
                    typescript_1.default.createExpressionStatement(typescript_1.default.createCall(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier('enums'), typescript_1.default.createIdentifier('push')), undefined, [typescript_1.default.createIdentifier('t')])),
                    typescript_1.default.createReturn(undefined)
                ], true), undefined),
                typescript_1.default.createIf(typescript_1.default.createBinary(typescript_1.default.createBinary(typescript_1.default.createBinary(typescript_1.default.createTypeOf(typescript_1.default.createIdentifier('t')), typescript_1.default.createToken(typescript_1.default.SyntaxKind.EqualsEqualsEqualsToken), typescript_1.default.createStringLiteral('function')), typescript_1.default.createToken(typescript_1.default.SyntaxKind.AmpersandAmpersandToken), typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier('t'), typescript_1.default.createIdentifier('prototype'))), typescript_1.default.createToken(typescript_1.default.SyntaxKind.AmpersandAmpersandToken), typescript_1.default.createPropertyAccess(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier('t'), typescript_1.default.createIdentifier('prototype')), typescript_1.default.createIdentifier('constructor'))), typescript_1.default.createBlock([
                    typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
                        typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier('instance'), undefined, typescript_1.default.createNew(typescript_1.default.createIdentifier('t'), undefined, [typescript_1.default.createIdentifier('db')]))
                    ], typescript_1.default.NodeFlags.Const)),
                    typescript_1.default.createIf(typescript_1.default.createBinary(typescript_1.default.createIdentifier('instance'), typescript_1.default.SyntaxKind.InstanceOfKeyword, typescript_1.default.createIdentifier('drizzle.AbstractTable')), typescript_1.default.createBlock([
                        typescript_1.default.createExpressionStatement(typescript_1.default.createCall(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier('tables'), typescript_1.default.createIdentifier('push')), undefined, [
                            typescript_1.default.createAsExpression(typescript_1.default.createAsExpression(typescript_1.default.createIdentifier('instance'), typescript_1.default.createKeywordTypeNode(typescript_1.default.SyntaxKind.UnknownKeyword)), typescript_1.default.createTypeReferenceNode(typescript_1.default.createQualifiedName(typescript_1.default.createIdentifier('drizzle'), typescript_1.default.createIdentifier('AbstractTable')), [
                                typescript_1.default.createKeywordTypeNode(typescript_1.default.SyntaxKind.AnyKeyword)
                            ]))
                        ]))
                    ], true), undefined)
                ], true), undefined)
            ], true))
        ]));
        blockStatements.push(iterationWithTypeChecks);
    }
    // return serializer.generate(tables, enums)
    blockStatements.push(typescript_1.default.createReturn(typescript_1.default.createCall(typescript_1.default.createPropertyAccess(typescript_1.default.createIdentifier("serializer"), typescript_1.default.createIdentifier("generate")), undefined, [
        typescript_1.default.createIdentifier("tables"),
        typescript_1.default.createIdentifier("enums"),
    ])));
    const funcStatement = [
        typescript_1.default.createVariableStatement(undefined, typescript_1.default.createVariableDeclarationList([
            typescript_1.default.createVariableDeclaration(typescript_1.default.createIdentifier("testFun"), undefined, typescript_1.default.createArrowFunction(undefined, undefined, [], undefined, typescript_1.default.createToken(typescript_1.default.SyntaxKind.EqualsGreaterThanToken), 
            // function body
            typescript_1.default.createBlock(blockStatements, true))),
        ], typescript_1.default.NodeFlags.Const)),
    ];
    const invocationStatement = [
        typescript_1.default.createExpressionStatement(typescript_1.default.createCall(typescript_1.default.createIdentifier("testFun"), undefined, [])),
    ];
    const outFile = typescript_1.default.createSourceFile("outfile.ts", "", typescript_1.default.ScriptTarget.ES2015, true, typescript_1.default.ScriptKind.TS);
    const source = [];
    source.push(...staticImports);
    source.push(...dynamicImports);
    source.push(...variablesStatements);
    source.push(...funcStatement);
    source.push(...invocationStatement);
    const newFile = typescript_1.default.factory.updateSourceFile(outFile, source);
    return printer.printFile(newFile);
};
exports.default = prepareFabricFile;
//# sourceMappingURL=factory.js.map