import {
    apply,
    applyTemplates,
    chain,
    MergeStrategy,
    mergeWith,
    move,
    Rule,
    SchematicsException,
    url
} from '@angular-devkit/schematics';
import {normalize, strings} from '@angular-devkit/core';

import {PluginOptions} from './PluginOptions';


const PLUGINS_DIST = 'projects/plugins/src';


export function plugin(_options: PluginOptions): Rule {
    return (_tree, _context) => {
        // create plugin's module, config and other stuff from the templates
        const templatesSource = apply(
            url('./files'), [
                applyTemplates({
                    classify: strings.classify,
                    dasherize: strings.dasherize,
                    name: _options.name,
                    displayName: _options.displayName || _options.name,
                }),
                move(normalize(`/${PLUGINS_DIST}/${strings.dasherize(_options.name)}`))
            ]
        )
        
        return chain([
            // externalSchematic('@schematics/angular', 'component', _options),
            mergeWith(templatesSource, MergeStrategy.Error),
            addBuildScriptRule(_options)
        ])
    }
}


/**
 * Adds command for building plugin to scripts section in package.json file.
 */
function addBuildScriptRule(_options: PluginOptions): Rule {
    return async (_tree, _context) => {
        const pkgPath = '/package.json';
        const pkg = _tree.readJson(pkgPath) as { scripts?: Record<string, string> } | null;
        if (pkg == null) {
            throw new SchematicsException('Could not find package.json');
        }

        const nameDasherized = strings.dasherize(_options.name);
        const buildCommand = `ng build plugins --module-path=./${nameDasherized}/${nameDasherized}.module#${strings.classify(_options.name)}Module`;
        // _context.logger.info(`Расширение успешно создано. Для его сборки воспользуйтесь командной:\n` + buildCommand);
        // const addScriptCommand = `npm pkg set script.build:${nameDasherized}=${buildCommand}`;

        pkg.scripts = {
            ...pkg.scripts,
            [`build:${nameDasherized}`]: buildCommand
        };

        _tree.overwrite(pkgPath, JSON.stringify(pkg, null, 2));
    };
}
