import { Helpers, _, UtilsMigrations, path, } from 'tnp-core/lib';
import { BaseDebounceCompilerForProject, UtilsTypescript, } from 'tnp-helpers/lib';
import { indexTsFromMigrationsFromSrc, libFromSrc, MIGRATION_CONST_PREFIX, migration_index_autogenerated_ts, migrationIndexAutogeneratedTsFileRelativeToSrcPath, migrationsFromLib, srcMainProject, THIS_IS_GENERATED_INFO_COMMENT, } from '../../../../../constants';
//#endregion
export class MigrationHelper extends BaseDebounceCompilerForProject {
    //#region constructor
    constructor(project) {
        super(project, {
            folderPath: project.pathFor([
                srcMainProject,
                libFromSrc,
                migrationsFromLib,
            ]),
            taskName: 'MigrationHelper',
            notifyOnFileUnlink: true,
        });
    }
    //#endregion
    //#region migration index autogenerated ts file
    get migrationIndexAutogeneratedTsFileAbsPath() {
        return this.project.pathFor([
            srcMainProject,
            migrationIndexAutogeneratedTsFileRelativeToSrcPath,
        ]);
    }
    //#endregion
    //#region rebuild
    rebuild(relativePathsWithClasses) {
        //#region @backendFunc
        Helpers.taskStarted(`Rebuilding migration index file...`);
        const allClassesByTimestamp = relativePathsWithClasses
            .reduce((acc, c) => acc.concat(c.classes), [])
            .sort((classA, classB) => {
            const timestampA = UtilsMigrations.getTimestampFromClassName(classA);
            const timestampB = UtilsMigrations.getTimestampFromClassName(classB);
            return timestampA - timestampB; // Ascending order
        });
        const allContexts = allClassesByTimestamp.reduce((alreadyAddedClassesObj, className) => {
            const contextName = _.first(className.split('_')) || '';
            if (!alreadyAddedClassesObj[contextName]) {
                alreadyAddedClassesObj[contextName] = [];
            }
            alreadyAddedClassesObj[contextName].push(className);
            return alreadyAddedClassesObj;
        }, {});
        const allImports = relativePathsWithClasses
            .filter(c => c.classes.length >= 1)
            .map(c => {
            return (`import { ${c.classes.join(', ')} } from ` +
                `'./${c.relativePath.replace('.ts', '')}';`);
        });
        // console.log('MigrationHelper rebuild for ', allImports);
        // export const MIGRATIONS_CLASSES = [${allClasses.join(',\n')}];
        Helpers.writeFile(this.migrationIndexAutogeneratedTsFileAbsPath, `
${THIS_IS_GENERATED_INFO_COMMENT}
${allImports.join('\n')}
${THIS_IS_GENERATED_INFO_COMMENT}
${_.keys(allContexts)
            .map(contextName => {
            const classes = allContexts[contextName];
            return (`export const ${MIGRATION_CONST_PREFIX}${contextName}` +
                ` = {${classes
                    .map(c => {
                    return `/* ${UtilsMigrations.getFormattedTimestampFromClassName(c)} */ ${c}`;
                })
                    .join(',\n ')}};`);
        })
            .join('\n')}
${THIS_IS_GENERATED_INFO_COMMENT}
      `);
        UtilsTypescript.formatFile(this.migrationIndexAutogeneratedTsFileAbsPath);
        Helpers.taskDone(`Rebuilding migration index Done`);
        //#endregion
    }
    //#endregion
    //#region action
    action({ changeOfFiles, asyncEvent, }) {
        //#region @backendFunc
        changeOfFiles = changeOfFiles.filter(c => {
            return (c.fileAbsolutePath.endsWith('.ts') &&
                path.basename(c.fileAbsolutePath) !== migration_index_autogenerated_ts);
        });
        if (changeOfFiles.length === 0) {
            // console.log('MigrationHelper action skipped');
            return;
        }
        if (!this.project.hasFile([
            srcMainProject,
            libFromSrc,
            migrationsFromLib,
            indexTsFromMigrationsFromSrc,
        ])) {
            Helpers.writeFile(this.project.pathFor([
                srcMainProject,
                libFromSrc,
                migrationsFromLib,
                indexTsFromMigrationsFromSrc,
            ]), `//@ts-nocheck
export * from './${migration_index_autogenerated_ts.replace('.ts', '')}';
        `.trim() + '\n');
        }
        // console.log('MigrationHelper action for ', changeOfFiles);
        this.rebuild(this.exitedFilesAbsPathes
            .filter(f => f.endsWith('.ts') && !f.endsWith('._auto-generated_.ts'))
            .map(c => {
            return {
                absPath: c,
                relativePath: this.project
                    .relative(c)
                    .split('/')
                    .slice(3)
                    .join('/'),
                classes: UtilsTypescript.extractClassNamesFromFile(c),
            };
        }));
        //#endregion
    }
}
//# sourceMappingURL=migrations-helper.js.map