"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Operation = void 0;
/**
 * The `Operation` class is a node in the dependency graph of work that needs to be scheduled by the
 * `OperationExecutionManager`. Each `Operation` has a `runner` member of type `IOperationRunner`, whose
 * implementation manages the actual process of running a single operation.
 *
 * The graph of `Operation` instances will be cloned into a separate execution graph after processing.
 *
 * @alpha
 */
class Operation {
    constructor(options) {
        /**
         * A set of all operations which depend on this operation.
         */
        this.consumers = new Set();
        /**
         * A set of all dependencies which must be executed before this operation is complete.
         */
        this.dependencies = new Set();
        /**
         * When the scheduler is ready to process this `Operation`, the `runner` implements the actual work of
         * running the operation.
         */
        this.runner = undefined;
        /**
         * The weight for this operation. This scalar is the contribution of this operation to the
         * `criticalPathLength` calculation above. Modify to indicate the following:
         * - `weight` === 1: indicates that this operation has an average duration
         * - `weight` &gt; 1: indicates that this operation takes longer than average and so the scheduler
         *     should try to favor starting it over other, shorter operations. An example might be an operation that
         *     bundles an entire application and runs whole-program optimization.
         * - `weight` &lt; 1: indicates that this operation takes less time than average and so the scheduler
         *     should favor other, longer operations over it. An example might be an operation to unpack a cached
         *     output, or an operation using NullOperationRunner, which might use a value of 0.
         */
        this.weight = 1;
        /**
         * Get the operation settings for this operation, defaults to the values defined in
         *  the project configuration.
         */
        this.settings = undefined;
        const { phase, project, runner, settings, logFilenameIdentifier } = options;
        this.associatedPhase = phase;
        this.associatedProject = project;
        this.runner = runner;
        this.settings = settings;
        this.logFilenameIdentifier = logFilenameIdentifier;
        this.enabled = true;
    }
    /**
     * The name of this operation, for logging.
     */
    get name() {
        const { runner } = this;
        if (!runner) {
            throw new Error(`Cannot get name of an Operation that does not yet have a runner.`);
        }
        return runner.name;
    }
    /**
     * If set to true, this operation is considered a no-op and can be considered always skipped for analysis purposes.
     */
    get isNoOp() {
        const { runner } = this;
        if (!runner) {
            throw new Error(`Cannot get isNoOp of an Operation that does not yet have a runner.`);
        }
        return !!runner.isNoOp;
    }
    /**
     * Adds the specified operation as a dependency and updates the consumer list.
     */
    addDependency(dependency) {
        // Cast internally to avoid adding the overhead of getters
        this.dependencies.add(dependency);
        dependency.consumers.add(this);
    }
    /**
     * Deletes the specified operation as a dependency and updates the consumer list.
     */
    deleteDependency(dependency) {
        // Cast internally to avoid adding the overhead of getters
        this.dependencies.delete(dependency);
        dependency.consumers.delete(this);
    }
}
exports.Operation = Operation;
//# sourceMappingURL=Operation.js.map