"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VersionPolicyConfiguration = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
const VersionPolicy_1 = require("./VersionPolicy");
const version_policies_schema_json_1 = __importDefault(require("../schemas/version-policies.schema.json"));
/**
 * Use this class to load and save the "common/config/rush/version-policies.json" config file.
 * This config file configures how different groups of projects will be published by Rush,
 * and how their version numbers will be determined.
 * @public
 */
class VersionPolicyConfiguration {
    /**
     * @internal
     */
    constructor(jsonFileName) {
        this._jsonFileName = jsonFileName;
        this.versionPolicies = new Map();
        this._loadFile();
    }
    /**
     * Validate the version policy configuration against the rush config
     */
    validate(projectsByName) {
        if (!this.versionPolicies) {
            return;
        }
        this.versionPolicies.forEach((policy) => {
            const lockStepPolicy = policy;
            if (lockStepPolicy.mainProject && !projectsByName.get(lockStepPolicy.mainProject)) {
                throw new Error(`Version policy \"${policy.policyName}\" has a non-existing mainProject:` +
                    ` ${lockStepPolicy.mainProject}.`);
            }
        });
    }
    /**
     * Gets the version policy by its name.
     * Throws error if the version policy is not found.
     * @param policyName - Name of the version policy
     */
    getVersionPolicy(policyName) {
        const policy = this.versionPolicies.get(policyName);
        if (!policy) {
            throw new Error(`Failed to find version policy by name \'${policyName}\'`);
        }
        return policy;
    }
    /**
     * Bumps up versions for the specified version policy or all version policies
     *
     * @param versionPolicyName - version policy name
     * @param bumpType - bump type to override what policy has defined.
     * @param identifier - prerelease identifier to override what policy has defined.
     * @param shouldCommit - should save to disk
     */
    bump(versionPolicyName, bumpType, identifier, shouldCommit) {
        if (versionPolicyName) {
            const policy = this.versionPolicies.get(versionPolicyName);
            if (policy) {
                policy.bump(bumpType, identifier);
            }
        }
        else {
            this.versionPolicies.forEach((versionPolicy) => {
                if (versionPolicy) {
                    versionPolicy.bump(bumpType, identifier);
                }
            });
        }
        this._saveFile(!!shouldCommit);
    }
    /**
     * Updates the version directly for the specified version policy
     * @param versionPolicyName - version policy name
     * @param newVersion - new version
     */
    update(versionPolicyName, newVersion, shouldCommit) {
        const policy = this.versionPolicies.get(versionPolicyName);
        if (!policy || !policy.isLockstepped) {
            throw new Error(`Lockstep Version policy with name "${versionPolicyName}" cannot be found`);
        }
        const lockStepVersionPolicy = policy;
        const previousVersion = lockStepVersionPolicy.version;
        if (lockStepVersionPolicy.update(newVersion)) {
            // eslint-disable-next-line no-console
            console.log(`\nUpdate version policy ${versionPolicyName} from ${previousVersion} to ${newVersion}`);
            this._saveFile(!!shouldCommit);
        }
    }
    _loadFile() {
        if (!node_core_library_1.FileSystem.exists(this._jsonFileName)) {
            return;
        }
        const versionPolicyJson = node_core_library_1.JsonFile.loadAndValidate(this._jsonFileName, VersionPolicyConfiguration._jsonSchema);
        versionPolicyJson.forEach((policyJson) => {
            const policy = VersionPolicy_1.VersionPolicy.load(policyJson);
            if (policy) {
                this.versionPolicies.set(policy.policyName, policy);
            }
        });
    }
    _saveFile(shouldCommit) {
        const versionPolicyJson = [];
        this.versionPolicies.forEach((versionPolicy) => {
            versionPolicyJson.push(versionPolicy._json);
        });
        if (shouldCommit) {
            node_core_library_1.JsonFile.save(versionPolicyJson, this._jsonFileName, { updateExistingFile: true });
        }
    }
}
exports.VersionPolicyConfiguration = VersionPolicyConfiguration;
VersionPolicyConfiguration._jsonSchema = node_core_library_1.JsonSchema.fromLoadedObject(version_policies_schema_json_1.default);
//# sourceMappingURL=VersionPolicyConfiguration.js.map