"use strict";
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to
//  deal in the Software without restriction, including without limitation the
//  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
//  sell copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateJsonFile = updateJsonFile;
exports.buildSelector = buildSelector;
exports.readIntoSourceFile = readIntoSourceFile;
exports.updateModuleChanges = updateModuleChanges;
exports.getBrowserProjectTargets = getBrowserProjectTargets;
exports.addStylesToAngularJson = addStylesToAngularJson;
exports.installPackageJsonDependencies = installPackageJsonDependencies;
exports.assembleDependencies = assembleDependencies;
exports.omitUpperPeerDependencyVersion = omitUpperPeerDependencyVersion;
const tslib_1 = require("tslib");
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const tasks_1 = require("@angular-devkit/schematics/tasks");
const schematics_2 = require("@angular/cdk/schematics");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const change_1 = require("@schematics/angular/utility/change");
const dependencies_1 = require("@schematics/angular/utility/dependencies");
const typescript_1 = tslib_1.__importDefault(require("typescript"));
const project_1 = require("./project");
const project_targets_1 = require("./project-targets");
const workspace_1 = require("./workspace");
const jsonc_parser_1 = require("jsonc-parser");
const lodash_1 = require("lodash");
function updateJsonFile(host, context, filename, propertyChain, itemToAdd, overrideValue = true) {
    if (!context.interactive) {
        console.info("not interactive");
    }
    const configPath = filename;
    if (host.exists(configPath)) {
        const jsonFileContent = host.read(configPath).toString("utf-8");
        const parsedJson = (0, jsonc_parser_1.parse)(jsonFileContent);
        const existingProps = (0, lodash_1.get)(parsedJson, propertyChain);
        if (typeof existingProps === "undefined") {
            const editedContent = getEdits(jsonFileContent, propertyChain, itemToAdd);
            host.overwrite(configPath, editedContent);
        }
        else {
            if (!overrideValue) {
                return host;
            }
            if (Array.isArray(existingProps) && Array.isArray(itemToAdd)) {
                // merge two arrays by uniq value
                const editedContent = getEdits(jsonFileContent, propertyChain, (0, lodash_1.uniqWith)((0, lodash_1.merge)([], [...existingProps, ...itemToAdd]), lodash_1.isEqual));
                host.overwrite(configPath, editedContent);
            }
        }
    }
    else {
        throw new schematics_1.SchematicsException("angular.json not found at " + configPath);
    }
    return host;
}
const getEdits = (jsonFileContent, propertyChain, modification) => {
    const edits = (0, jsonc_parser_1.modify)(jsonFileContent, propertyChain, modification, {
        isArrayInsertion: true,
    });
    return (0, jsonc_parser_1.applyEdits)(jsonFileContent, edits);
};
function buildSelector(options, projectPrefix) {
    let selector = core_1.strings.dasherize(options.name);
    if (options.prefix) {
        selector = `${options.prefix}-${selector}`;
    }
    else if (options.prefix === undefined && projectPrefix) {
        selector = `${projectPrefix}-${selector}`;
    }
    return selector;
}
function readIntoSourceFile(host, modulePath) {
    const text = host.read(modulePath);
    if (text === null) {
        throw new schematics_1.SchematicsException(`File ${modulePath} does not exist.`);
    }
    const sourceText = text.toString("utf-8");
    return typescript_1.default.createSourceFile(modulePath, sourceText, typescript_1.default.ScriptTarget.Latest, true);
}
function updateModuleChanges(host, options, moduleSource, modules, providers = [], declarations = []) {
    const modulePath = options.module;
    const declarationRecorder = host.beginUpdate(modulePath);
    declarations.forEach((item) => {
        const changeList = (0, ast_utils_1.addDeclarationToModule)(moduleSource, modulePath, item.item, item.path);
        changeList.forEach((change) => {
            if (change instanceof change_1.InsertChange) {
                declarationRecorder.insertLeft(change.pos, change.toAdd);
            }
        });
    });
    providers.forEach((item) => {
        const changeList = (0, ast_utils_1.addProviderToModule)(moduleSource, modulePath, item.item, item.path);
        changeList.forEach((change) => {
            if (change instanceof change_1.InsertChange) {
                declarationRecorder.insertLeft(change.pos, change.toAdd);
            }
        });
    });
    modules.forEach((item) => {
        if (!(0, ast_utils_1.isImported)(moduleSource, item.item, item.path)) {
            const moduleChanges = (0, schematics_2.addImportToModule)(moduleSource, modulePath, item.item, item.path);
            moduleChanges.forEach((change) => {
                if (change instanceof change_1.InsertChange) {
                    declarationRecorder.insertLeft(change.pos, change.toAdd);
                }
            });
        }
    });
    host.commitUpdate(declarationRecorder);
}
function getBrowserProjectTargets(host, options) {
    const workspace = (0, workspace_1.getWorkspace)(host);
    const clientProject = (0, project_1.getProject)(workspace, options.project);
    // @ts-ignore: Avoiding strict mode errors, preserving old behavior
    return (0, project_targets_1.getProjectTargets)(clientProject)["build"];
}
function addStylesToAngularJson(options, stylePaths) {
    return (host, context) => updateJsonFile(host, context, "angular.json", [
        "projects",
        options.project,
        "architect",
        "build",
        "options",
        "styles",
    ], stylePaths);
}
function installPackageJsonDependencies() {
    return (host, context) => {
        context.addTask(new tasks_1.NodePackageInstallTask());
        context.logger.info(` Installing packages...`);
        return host;
    };
}
function assembleDependencies(dependencies) {
    return Object.keys(dependencies).map((key) => ({
        type: dependencies_1.NodeDependencyType.Default,
        version: omitUpperPeerDependencyVersion(dependencies[key]),
        name: key,
        overwrite: true,
    }));
}
function omitUpperPeerDependencyVersion(version) {
    return version.split("||")[0].trim();
}
//# sourceMappingURL=schematics-helper.js.map