import chalk from 'chalk';
import BaseApplicationGenerator from '../base-application/index.mjs';
import JSONToJDLEntityConverter from '../../jdl/converters/json-to-jdl-entity-converter.js';
import JSONToJDLOptionConverter from '../../jdl/converters/json-to-jdl-option-converter.js';
import { YO_RC_FILE } from '../generator-constants.mjs';
import { replaceSensitiveConfig } from './support/utils.mjs';
const isInfoCommand = commandName => commandName === 'info' || undefined;
export default class InfoGenerator extends BaseApplicationGenerator {
    constructor(args, options, features) {
        super(args, options, {
            jhipsterBootstrap: false,
            storeJHipsterVersion: false,
            customInstallTask: isInfoCommand(options.commandName),
            customCommitTask: isInfoCommand(options.commandName),
            ...features,
        });
    }
    get [BaseApplicationGenerator.INITIALIZING]() {
        return this.asInitializingTaskGroup({
            sayHello() {
                this.log.log(chalk.white('Welcome to the JHipster Information Sub-Generator\n'));
            },
            async checkJHipster() {
                const { stdout } = await this.spawnCommand('npm list generator-begcode', { stdio: 'pipe', reject: false });
                console.log(`\n\`\`\`\n${stdout}\`\`\`\n`);
            },
            displayConfiguration() {
                const yoRc = this.readDestinationJSON(YO_RC_FILE);
                if (yoRc) {
                    const result = JSON.stringify(replaceSensitiveConfig(yoRc), null, 2);
                    console.log(`\n##### **JHipster configuration, a \`${YO_RC_FILE}\` file generated in the root folder**\n`);
                    console.log(`\n<details>\n<summary>${YO_RC_FILE} file</summary>\n<pre>\n${result}\n</pre>\n</details>\n`);
                }
                else {
                    console.log('\n##### **JHipster configuration not found**\n');
                }
                const packages = this.jhipsterConfig.appsFolders ?? this.jhipsterConfig.packages ?? [];
                if (packages.length > 0) {
                    for (const pkg of packages) {
                        const yoRc = this.readDestinationJSON(this.destinationPath(pkg, YO_RC_FILE));
                        if (yoRc) {
                            const result = JSON.stringify(replaceSensitiveConfig(yoRc), null, 2);
                            console.log(`\n<details>\n<summary>${YO_RC_FILE} file for ${pkg}</summary>\n<pre>\n${result}\n</pre>\n</details>\n`);
                        }
                        else {
                            console.log(`\n##### **BegCode configuration for ${pkg} not found**\n`);
                        }
                    }
                }
            },
            async checkJava() {
                console.log('\n##### **Environment and Tools**\n');
                await this.checkCommand('java', ['-version'], ({ stderr }) => console.log(stderr));
                console.log();
            },
            async checkGit() {
                await this.checkCommand('git', ['version']);
                console.log();
            },
            async checkNode() {
                await this.checkCommand('node', ['-v'], ({ stdout }) => console.log(`node: ${stdout}`));
            },
            async checkNpm() {
                await this.checkCommand('npm', ['-v'], ({ stdout }) => console.log(`npm: ${stdout}`));
                console.log();
            },
            async checkDocker() {
                await this.checkCommand('docker', ['-v']);
            },
            checkApplication() {
                if (this.jhipsterConfig.baseName === undefined) {
                    this.log.warn("Current location doesn't contain a valid JHipster application");
                    this.cancelCancellableTasks();
                }
            },
            displayEntities() {
                console.log('\n##### **JDL for the Entity configuration(s) `entityName.json` files generated in the `.jhipster` directory**\n');
                const jdl = this.generateJDLFromEntities();
                console.log('<details>\n<summary>JDL entity definitions</summary>\n');
                console.log(`<pre>\n${jdl?.toString()}\n</pre>\n</details>\n`);
            },
        });
    }
    async checkCommand(command, args, printInfo = ({ stdout }) => console.log(stdout)) {
        try {
            printInfo(await this.spawn(command, args, { stdio: 'pipe' }));
        }
        catch (_error) {
            console.log(chalk.red(`'${command}' command could not be found`));
        }
    }
    generateJDLFromEntities() {
        let jdlObject;
        const entities = new Map();
        try {
            this.getExistingEntities().forEach(entity => {
                entities.set(entity.name, entity.definition);
            });
            jdlObject = JSONToJDLEntityConverter.convertEntitiesToJDL({
                entities,
            });
            JSONToJDLOptionConverter.convertServerOptionsToJDL({ 'generator-begcode': this.config.getAll() }, jdlObject);
        }
        catch (error) {
            this.log.error('Error while parsing entities to JDL', error);
            throw new Error('\nError while parsing entities to JDL\n', { cause: error });
        }
        return jdlObject;
    }
}
