// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
import { randomUUID } from 'node:crypto';
import { FileSystem, JsonFile, JsonSchema } from '@rushstack/node-core-library';
import { EnvironmentConfiguration } from './EnvironmentConfiguration';
import { RushConstants } from '../logic/RushConstants';
import schemaJson from '../schemas/cobuild.schema.json';
/**
 * Use this class to load and save the "common/config/rush/cobuild.json" config file.
 * This file provides configuration options for the Rush Cobuild feature.
 * @beta
 */
export class CobuildConfiguration {
    constructor(options) {
        var _a, _b;
        const { cobuildJson, cobuildLockProviderFactory, rushConfiguration } = options;
        this.cobuildContextId = EnvironmentConfiguration.cobuildContextId;
        this.cobuildFeatureEnabled = this.cobuildContextId ? cobuildJson.cobuildFeatureEnabled : false;
        this.cobuildRunnerId = EnvironmentConfiguration.cobuildRunnerId || randomUUID();
        this.cobuildLeafProjectLogOnlyAllowed =
            (_a = EnvironmentConfiguration.cobuildLeafProjectLogOnlyAllowed) !== null && _a !== void 0 ? _a : false;
        this.cobuildWithoutCacheAllowed =
            (_b = rushConfiguration.experimentsConfiguration.configuration.allowCobuildWithoutCache) !== null && _b !== void 0 ? _b : false;
        this._cobuildLockProviderFactory = cobuildLockProviderFactory;
        this._cobuildJson = cobuildJson;
    }
    /**
     * Attempts to load the cobuild.json data from the standard file path `common/config/rush/cobuild.json`.
     * If the file has not been created yet, then undefined is returned.
     */
    static async tryLoadAsync(terminal, rushConfiguration, rushSession) {
        const jsonFilePath = CobuildConfiguration.getCobuildConfigFilePath(rushConfiguration);
        try {
            return await CobuildConfiguration._loadAsync(jsonFilePath, terminal, rushConfiguration, rushSession);
        }
        catch (err) {
            if (!FileSystem.isNotExistError(err)) {
                throw err;
            }
        }
    }
    static getCobuildConfigFilePath(rushConfiguration) {
        return `${rushConfiguration.commonRushConfigFolder}/${RushConstants.cobuildFilename}`;
    }
    static async _loadAsync(jsonFilePath, terminal, rushConfiguration, rushSession) {
        let cobuildJson;
        try {
            cobuildJson = await JsonFile.loadAndValidateAsync(jsonFilePath, CobuildConfiguration._jsonSchema);
        }
        catch (e) {
            if (FileSystem.isNotExistError(e)) {
                return undefined;
            }
            throw e;
        }
        if (!(cobuildJson === null || cobuildJson === void 0 ? void 0 : cobuildJson.cobuildFeatureEnabled)) {
            return undefined;
        }
        const cobuildLockProviderFactory = rushSession.getCobuildLockProviderFactory(cobuildJson.cobuildLockProvider);
        if (!cobuildLockProviderFactory) {
            throw new Error(`Unexpected cobuild lock provider: ${cobuildJson.cobuildLockProvider}`);
        }
        return new CobuildConfiguration({
            cobuildJson,
            rushConfiguration,
            rushSession,
            cobuildLockProviderFactory
        });
    }
    async createLockProviderAsync(terminal) {
        if (this.cobuildFeatureEnabled) {
            terminal.writeLine(`Running cobuild (runner ${this.cobuildContextId}/${this.cobuildRunnerId})`);
            const cobuildLockProvider = await this._cobuildLockProviderFactory(this._cobuildJson);
            this._cobuildLockProvider = cobuildLockProvider;
            await this._cobuildLockProvider.connectAsync();
        }
    }
    async destroyLockProviderAsync() {
        var _a;
        if (this.cobuildFeatureEnabled) {
            await ((_a = this._cobuildLockProvider) === null || _a === void 0 ? void 0 : _a.disconnectAsync());
        }
    }
    getCobuildLockProvider() {
        if (!this._cobuildLockProvider) {
            throw new Error(`Cobuild lock provider has not been created`);
        }
        return this._cobuildLockProvider;
    }
}
CobuildConfiguration._jsonSchema = JsonSchema.fromLoadedObject(schemaJson);
//# sourceMappingURL=CobuildConfiguration.js.map