import { getConfigWithDefaults } from "../../lib/jhipster/default-application-options.js";
import { createDelayedMutationContext, mutateData } from "../../lib/utils/index.js";
import BaseGenerator from "../base/index.js";
import { PRIORITY_NAMES } from "../base-core/priorities.js";
import { sanitizeConfigForNodeApplications } from "./support/config-hardening.js";
import { CONTEXT_DATA_APPLICATION_KEY, CONTEXT_DATA_SANITIZATION_KEY, CONTEXT_DATA_SOURCE_KEY } from "./support/index.js";
const { LOADING, COMPOSING_BOOTSTRAP, PREPARING, POST_PREPARING, DEFAULT, WRITING, POST_WRITING, PRE_CONFLICTS, INSTALL, END } = PRIORITY_NAMES;
const PRIORITY_WITH_SOURCE = new Set([PREPARING, POST_PREPARING, POST_WRITING]);
const PRIORITY_WITH_APPLICATION_DEFAULTS = new Set([PREPARING, LOADING]);
const PRIORITY_WITH_APPLICATION = new Set([
    LOADING,
    COMPOSING_BOOTSTRAP,
    PREPARING,
    POST_PREPARING,
    DEFAULT,
    WRITING,
    POST_WRITING,
    PRE_CONFLICTS,
    INSTALL,
    END,
]);
const getFirstArgForPriority = (priorityName) => ({
    source: PRIORITY_WITH_SOURCE.has(priorityName),
    application: PRIORITY_WITH_APPLICATION.has(priorityName),
    applicationDefaults: PRIORITY_WITH_APPLICATION_DEFAULTS.has(priorityName),
});
/**
 * This is the base class for a generator that generates entities.
 */
export default class BaseSimpleApplicationGenerator extends BaseGenerator {
    constructor(args, options, features) {
        super(args, options, {
            storeJHipsterVersion: true,
            storeBlueprintVersion: true,
            skipLoadCommand: false,
            configTransform: (...args) => {
                const configTransform = this.getContextData(CONTEXT_DATA_SANITIZATION_KEY, {
                    factory: () => (config, configKey) => {
                        const cleanups = sanitizeConfigForNodeApplications(config, { depth: -1, keyPath: configKey });
                        for (const [key, { oldValue, newValue }] of Object.entries(cleanups)) {
                            this.log.warn(`The configuration property '${key}' contained a template literal which has been sanitized for security hardening. Original value: '${oldValue}', new value: '${newValue}'`);
                        }
                        return config;
                    },
                });
                return configTransform(...args);
            },
            ...features,
        });
    }
    get context() {
        return this.#application;
    }
    get #source() {
        return this.getContextData(CONTEXT_DATA_SOURCE_KEY, { factory: () => ({}) });
    }
    get #application() {
        return this.getContextData(CONTEXT_DATA_APPLICATION_KEY, {
            factory: () => createDelayedMutationContext({ autoDelay: true }),
        });
    }
    /**
     * JHipster config with default values fallback
     */
    get jhipsterConfigWithDefaults() {
        return getConfigWithDefaults(super.jhipsterConfigWithDefaults);
    }
    /**
     * @deprecated use dependsOnBootstrap('common'), dependsOnBootstrap('base-application') or dependsOnBootstrap('base-simple-application')
     */
    dependsOnBootstrapApplicationBase(options) {
        return this.dependsOnJHipster('jhipster:base-application:bootstrap', options);
    }
    getArgsForPriority(priorityName) {
        const args = super.getArgsForPriority(priorityName);
        let firstArg = this.getTaskFirstArgForPriority(priorityName);
        if (args.length > 0) {
            firstArg = { ...args[0], ...firstArg };
        }
        return [firstArg];
    }
    /**
     * @protected
     */
    getTaskFirstArgForPriority(priorityName) {
        return this.getApplicationArgForPriority(getFirstArgForPriority(priorityName));
    }
    getApplicationArgForPriority({ source, application, applicationDefaults, }) {
        const taskArg = {};
        if (application) {
            taskArg.application = this.#application;
        }
        if (applicationDefaults) {
            taskArg.applicationDefaults = (...args) => mutateData(this.#application, ...args.map(data => ({ __override__: false, ...data })));
        }
        if (source) {
            taskArg.source = this.#source;
        }
        return taskArg;
    }
    /**
     * Utility method to get typed objects for autocomplete.
     */
    asBootstrapApplicationTaskGroup(taskGroup) {
        return taskGroup;
    }
}
