import BaseApplicationGenerator from '../base-application/index.mjs';
import { GENERATOR_SPRING_CACHE, GENERATOR_BOOTSTRAP_APPLICATION } from '../generator-list.mjs';
import writeTask from './files.mjs';
import cleanupTask from './cleanup.mjs';
import { createNeedleCallback } from '../base/support/needles.mjs';
import { getCacheProviderMavenDefinition } from './internal/dependencies.mjs';
export default class SpringCacheGenerator extends BaseApplicationGenerator {
    async beforeQueue() {
        if (!this.fromBlueprint) {
            await this.composeWithBlueprints(GENERATOR_SPRING_CACHE);
        }
        if (!this.delegateToBlueprint) {
            await this.dependsOnJHipster(GENERATOR_BOOTSTRAP_APPLICATION);
        }
    }
    get preparing() {
        return this.asPreparingTaskGroup({
            addNeedles({ source, application }) {
                if (application.cacheProviderEhcache ||
                    application.cacheProviderCaffeine ||
                    application.cacheProviderRedis) {
                    const cacheConfigurationFile = `${application.javaPackageSrcDir}config/CacheConfiguration.java`;
                    const needle = `${application.cacheProvider}-add-entry`;
                    const useJcacheConfiguration = application.cacheProviderRedis;
                    const addEntryToCacheCallback = entry => createNeedleCallback({
                        needle,
                        contentToAdd: `createCache(cm, ${entry}${useJcacheConfiguration ? ', jcacheConfiguration' : ''});`,
                    });
                    source.addEntryToCache = ({ entry }) => this.editFile(cacheConfigurationFile, addEntryToCacheCallback(entry));
                    source.addEntityToCache = ({ entityAbsoluteClass, relationships }) => {
                        const entry = `${entityAbsoluteClass}.class.getName()`;
                        this.editFile(cacheConfigurationFile, addEntryToCacheCallback(entry), ...(relationships ?? [])
                            .filter(rel => rel.collection)
                            .map(rel => addEntryToCacheCallback(`${entry} + ".${rel.propertyName}"`)));
                    };
                }
                else {
                    source.addEntryToCache = () => { };
                    source.addEntityToCache = () => { };
                }
            },
        });
    }
    get [BaseApplicationGenerator.PREPARING]() {
        return this.delegateTasksToBlueprint(() => this.preparing);
    }
    get writing() {
        return this.asWritingTaskGroup({
            cleanupTask,
            writeTask,
        });
    }
    get [BaseApplicationGenerator.WRITING]() {
        return this.delegateTasksToBlueprint(() => this.writing);
    }
    get postWriting() {
        return this.asPostWritingTaskGroup({
            addTestSpringFactory({ source, application }) {
                if (application.cacheProviderRedis) {
                    source.addTestSpringFactory?.({
                        key: 'org.springframework.test.context.ContextCustomizerFactory',
                        value: `${application.packageName}.config.RedisTestContainersSpringContextCustomizerFactory`,
                    });
                }
            },
            applyGradleScript({ source, application }) {
                if (application.buildToolGradle) {
                    source.applyFromGradle?.({ script: 'gradle/cache.gradle' });
                }
            },
            addDependencies({ application, source }) {
                if (application.buildToolMaven) {
                    if (!application.javaDependencies) {
                        throw new Error('Some application fields are be mandatory');
                    }
                    const applicationAny = application;
                    source.addMavenDependency?.({
                        groupId: 'org.springframework.boot',
                        artifactId: 'spring-boot-starter-cache',
                    });
                    const definition = getCacheProviderMavenDefinition(applicationAny.cacheProvider, application.javaDependencies, applicationAny.javaVersion, application.ormTool);
                    source.addMavenDefinition?.(definition.base);
                    if (applicationAny.enableHibernateCache && definition.hibernateCache) {
                        source.addMavenDefinition?.(definition.hibernateCache);
                    }
                }
            },
        });
    }
    get [BaseApplicationGenerator.POST_WRITING]() {
        return this.asPostWritingTaskGroup(this.delegateTasksToBlueprint(() => this.postWriting));
    }
    get postWritingEntities() {
        return this.asPostWritingEntitiesTaskGroup({
            customizeFiles({ application, entities, source }) {
                if (application.databaseTypeSql) {
                    for (const entity of entities.filter(entity => !entity.skipServer && !entity.builtIn)) {
                        source.addEntityToCache?.({
                            entityAbsoluteClass: entity.entityAbsoluteClass,
                            relationships: entity.relationships,
                        });
                    }
                }
            },
        });
    }
    get [BaseApplicationGenerator.POST_WRITING_ENTITIES]() {
        return this.asPostWritingEntitiesTaskGroup(this.delegateTasksToBlueprint(() => this.postWritingEntities));
    }
}
