import { forceYoFiles, createConflicterTransform, createYoResolveTransform } from '@yeoman/conflicter';
import { isFilePending } from 'mem-fs-editor/state';
import BaseGenerator from '../base/index.mjs';
import { createMultiStepTransform, createPrettierTransform, createForceWriteConfigFilesTransform, autoCrlfTransform, isPrettierConfigFilePath, createSortConfigFilesTransform, createESLintTransform, createRemoveUnusedImportsTransform, } from './support/index.mjs';
import { PRETTIER_EXTENSIONS } from '../generator-constants.mjs';
import { GENERATOR_UPGRADE } from '../generator-list.mjs';
import { PRIORITY_NAMES, QUEUES } from '../base-application/priorities.mjs';
import command from './command.mjs';
import { loadStoredAppOptions } from '../app/support/index.mjs';
const { MULTISTEP_TRANSFORM, PRE_CONFLICTS } = PRIORITY_NAMES;
const { MULTISTEP_TRANSFORM_QUEUE, PRE_CONFLICTS_QUEUE } = QUEUES;
const MULTISTEP_TRANSFORM_PRIORITY = BaseGenerator.asPriority(MULTISTEP_TRANSFORM);
const PRE_CONFLICTS_PRIORITY = BaseGenerator.asPriority(PRE_CONFLICTS);
export default class BootstrapGenerator extends BaseGenerator {
    static MULTISTEP_TRANSFORM = MULTISTEP_TRANSFORM_PRIORITY;
    static PRE_CONFLICTS = PRE_CONFLICTS_PRIORITY;
    upgradeCommand;
    skipPrettier;
    constructor(args, options, features) {
        super(args, options, { jhipsterBootstrap: false, uniqueGlobally: true, customCommitTask: () => this.commitSharedFs(), ...features });
    }
    beforeQueue() {
        loadStoredAppOptions.call(this);
        this.env.options.nodePackageManager = 'npm';
        this.upgradeCommand = this.options.commandName === GENERATOR_UPGRADE;
    }
    get initializing() {
        return this.asInitializingTaskGroup({
            loadOptions() {
                this.parseJHipsterOptions(command.options);
            },
            validateBlueprint() {
                if (this.jhipsterConfig.blueprints && !this.skipChecks) {
                    this.jhipsterConfig.blueprints.forEach(blueprint => {
                        this._checkJHipsterBlueprintVersion(blueprint.name);
                        this._checkBlueprint(blueprint.name);
                    });
                }
            },
        });
    }
    get [BaseGenerator.INITIALIZING]() {
        return this.delegateTasksToBlueprint(() => this.initializing);
    }
    get multistepTransform() {
        return {
            queueTransform() {
                this.queueMultistepTransform();
                this.env.sharedFs.on('change', filePath => {
                    if (createMultiStepTransform().templateFileFs.isTemplate(filePath)) {
                        this.queueMultistepTransform();
                    }
                });
            },
        };
    }
    get [MULTISTEP_TRANSFORM_PRIORITY]() {
        return this.multistepTransform;
    }
    get preConflicts() {
        return {
            async queueCommitPrettierConfig() {
                await this.queueCommitPrettierConfig();
                this.env.sharedFs.on('change', filePath => {
                    if (isPrettierConfigFilePath(filePath)) {
                        this.queueCommitPrettierConfig();
                    }
                });
            },
        };
    }
    get [PRE_CONFLICTS_PRIORITY]() {
        return this.preConflicts;
    }
    queueMultistepTransform() {
        this.queueTask({
            method: () => {
                const multiStepTransform = createMultiStepTransform();
                const filter = file => isFilePending(file) && multiStepTransform.templateFileFs.isTemplate(file.path);
                return this.env.applyTransforms([multiStepTransform], {
                    name: 'applying multi-step templates',
                    streamOptions: { filter },
                });
            },
            taskName: MULTISTEP_TRANSFORM_QUEUE,
            queueName: MULTISTEP_TRANSFORM_QUEUE,
            once: true,
        });
    }
    queueCommitPrettierConfig() {
        this.queueTask({
            method: async () => {
                await this.commitPrettierConfig();
            },
            taskName: 'commitPrettierConfig',
            queueName: PRE_CONFLICTS_QUEUE,
            once: true,
        });
    }
    async commitPrettierConfig() {
        const filter = file => isFilePending(file) && isPrettierConfigFilePath(file.path);
        await this.commitSharedFs(this.env.sharedFs.stream({ filter }));
        this.log.ok('committed prettier configuration files');
    }
    async commitSharedFs(stream = this.env.sharedFs.stream({ filter: isFilePending })) {
        const { skipYoResolve } = this.options;
        const ignoreErrors = this.options.ignoreErrors || this.upgradeCommand;
        const transformStreams = [
            ...(skipYoResolve ? [] : [createYoResolveTransform()]),
            forceYoFiles(),
            createSortConfigFilesTransform(),
            createForceWriteConfigFilesTransform(),
            ...(this.skipPrettier
                ? []
                : [
                    createESLintTransform.call(this, { ignoreErrors, extensions: 'ts,js' }),
                    createRemoveUnusedImportsTransform.call(this, { ignoreErrors }),
                    await createPrettierTransform.call(this, {
                        ignoreErrors,
                        prettierPackageJson: true,
                        prettierJava: !this.jhipsterConfig.skipServer,
                        extensions: PRETTIER_EXTENSIONS,
                    }),
                ]),
            ...(this.jhipsterConfig.autoCrlf ? [autoCrlfTransform(this.createGit())] : []),
            createConflicterTransform(this.env.adapter, { ...this.env.conflicterOptions, memFs: this.env.sharedFs }),
        ];
        await this.fs.commit(transformStreams, stream);
    }
}
