import { buildToolTypes } from '../../../../jdl/index.js';
import BaseApplicationGenerator from '../../../base-application/index.js';
import { GENERATOR_GRADLE, GENERATOR_MAVEN } from '../../../generator-list.js';
import { javaScopeToGradleScope } from '../../support/index.js';
const { GRADLE, MAVEN } = buildToolTypes;
export default class BuildToolGenerator extends BaseApplicationGenerator {
    async beforeQueue() {
        if (!this.fromBlueprint) {
            await this.composeWithBlueprints();
        }
        if (!this.delegateToBlueprint) {
            await this.dependsOnJHipster('begcode:java:bootstrap');
        }
    }
    get initializing() {
        return this.asInitializingTaskGroup({
            async initializing() {
                await this.parseCurrentJHipsterCommand();
            },
        });
    }
    get [BaseApplicationGenerator.INITIALIZING]() {
        return this.delegateTasksToBlueprint(() => this.initializing);
    }
    get prompting() {
        return this.asPromptingTaskGroup({
            async promptCommand({ control }) {
                if (control.existingProject && this.options.askAnswered !== true)
                    return;
                await this.promptCurrentJHipsterCommand();
            },
        });
    }
    get [BaseApplicationGenerator.PROMPTING]() {
        return this.delegateTasksToBlueprint(() => this.prompting);
    }
    get composing() {
        return this.asComposingTaskGroup({
            async composing() {
                const { buildTool } = this.jhipsterConfigWithDefaults;
                if (buildTool === GRADLE) {
                    await this.composeWithJHipster(GENERATOR_GRADLE);
                }
                else if (buildTool === MAVEN) {
                    await this.composeWithJHipster(GENERATOR_MAVEN);
                }
                else {
                    throw new Error(`Build tool ${buildTool} is not supported`);
                }
            },
        });
    }
    get [BaseApplicationGenerator.COMPOSING]() {
        return this.delegateTasksToBlueprint(() => this.composing);
    }
    get preparing() {
        return this.asPreparingTaskGroup({
            prepareJavaApplication({ application, source }) {
                source.addJavaDependencies = (dependencies, options) => {
                    if (application.buildToolMaven) {
                        const annotationProcessors = dependencies.filter(dep => dep.scope === 'annotationProcessor');
                        const importDependencies = dependencies.filter(dep => dep.scope === 'import');
                        const commonDependencies = dependencies.filter(dep => !['annotationProcessor', 'import'].includes(dep.scope));
                        const convertVersionToRef = ({ version, versionRef, ...artifact }) => version || versionRef ? { ...artifact, version: `\${${versionRef ?? artifact.artifactId}.version}` } : artifact;
                        const removeScope = ({ scope: _scope, ...artifact }) => artifact;
                        source.addMavenDefinition?.({
                            properties: dependencies
                                .filter(dep => dep.version)
                                .map(({ artifactId, version }) => ({ property: `${artifactId}.version`, value: version })),
                            dependencies: [
                                ...commonDependencies.map(convertVersionToRef),
                                ...annotationProcessors.filter(dep => !dep.version).map(artifact => ({ ...artifact, scope: 'provided' })),
                            ],
                            dependencyManagement: importDependencies.map(convertVersionToRef),
                            annotationProcessors: annotationProcessors.map(convertVersionToRef).map(removeScope),
                        });
                    }
                    if (application.buildToolGradle) {
                        source.addGradleDependencies?.(dependencies
                            .filter(dep => !dep.version && !dep.versionRef)
                            .map(({ scope, type, ...artifact }) => ({
                            ...artifact,
                            scope: javaScopeToGradleScope({ scope, type }),
                        })), options);
                        source.addGradleDependencyCatalogLibraries?.(dependencies
                            .filter(dep => dep.version || dep.versionRef)
                            .map(({ scope, type, groupId, artifactId, version, versionRef }) => {
                            const library = {
                                libraryName: artifactId,
                                module: `${groupId}:${artifactId}`,
                                scope: javaScopeToGradleScope({ scope, type }),
                            };
                            return version ? { ...library, version } : { ...library, 'version.ref': versionRef };
                        }), options);
                    }
                };
                source.addJavaDefinition = (definition, options) => {
                    const { dependencies, versions } = definition;
                    if (dependencies) {
                        source.addJavaDependencies(dependencies.filter(dep => {
                            if (dep.versionRef) {
                                return versions?.find(({ name }) => name === dep.versionRef)?.version;
                            }
                            return true;
                        }), options);
                    }
                    if (versions) {
                        if (application.buildToolMaven) {
                            source.addMavenDefinition({
                                properties: versions.filter(v => v.version).map(({ name, version }) => ({ property: `${name}.version`, value: version })),
                            });
                        }
                        if (application.buildToolGradle) {
                            source.addGradleDependencyCatalogVersions?.(versions, options);
                        }
                    }
                };
            },
        });
    }
    get [BaseApplicationGenerator.PREPARING]() {
        return this.delegateTasksToBlueprint(() => this.preparing);
    }
}
