'use strict';

var cancellation = require('../../../../../../../_virtual/cancellation2.js');
var ral = require('./ral.js');
var is = require('./is.js');
var events = require('./events.js');

var hasRequiredCancellation;

function requireCancellation () {
	if (hasRequiredCancellation) return cancellation.__exports;
	hasRequiredCancellation = 1;
	/*---------------------------------------------------------------------------------------------
	 *  Copyright (c) Microsoft Corporation. All rights reserved.
	 *  Licensed under the MIT License. See License.txt in the project root for license information.
	 *--------------------------------------------------------------------------------------------*/
	Object.defineProperty(cancellation.__exports, "__esModule", { value: true });
	cancellation.__exports.CancellationTokenSource = cancellation.__exports.CancellationToken = void 0;
	const ral_1 = ral.__require();
	const Is = is.__require();
	const events_1 = events.__require();
	var CancellationToken;
	(function (CancellationToken) {
	    CancellationToken.None = Object.freeze({
	        isCancellationRequested: false,
	        onCancellationRequested: events_1.Event.None
	    });
	    CancellationToken.Cancelled = Object.freeze({
	        isCancellationRequested: true,
	        onCancellationRequested: events_1.Event.None
	    });
	    function is(value) {
	        const candidate = value;
	        return candidate && (candidate === CancellationToken.None
	            || candidate === CancellationToken.Cancelled
	            || (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested));
	    }
	    CancellationToken.is = is;
	})(CancellationToken || (cancellation.__exports.CancellationToken = CancellationToken = {}));
	const shortcutEvent = Object.freeze(function (callback, context) {
	    const handle = (0, ral_1.default)().timer.setTimeout(callback.bind(context), 0);
	    return { dispose() { handle.dispose(); } };
	});
	class MutableToken {
	    constructor() {
	        this._isCancelled = false;
	    }
	    cancel() {
	        if (!this._isCancelled) {
	            this._isCancelled = true;
	            if (this._emitter) {
	                this._emitter.fire(undefined);
	                this.dispose();
	            }
	        }
	    }
	    get isCancellationRequested() {
	        return this._isCancelled;
	    }
	    get onCancellationRequested() {
	        if (this._isCancelled) {
	            return shortcutEvent;
	        }
	        if (!this._emitter) {
	            this._emitter = new events_1.Emitter();
	        }
	        return this._emitter.event;
	    }
	    dispose() {
	        if (this._emitter) {
	            this._emitter.dispose();
	            this._emitter = undefined;
	        }
	    }
	}
	class CancellationTokenSource {
	    get token() {
	        if (!this._token) {
	            // be lazy and create the token only when
	            // actually needed
	            this._token = new MutableToken();
	        }
	        return this._token;
	    }
	    cancel() {
	        if (!this._token) {
	            // save an object by returning the default
	            // cancelled token when cancellation happens
	            // before someone asks for the token
	            this._token = CancellationToken.Cancelled;
	        }
	        else {
	            this._token.cancel();
	        }
	    }
	    dispose() {
	        if (!this._token) {
	            // ensure to initialize with an empty token if we had none
	            this._token = CancellationToken.None;
	        }
	        else if (this._token instanceof MutableToken) {
	            // actually dispose
	            this._token.dispose();
	        }
	    }
	}
	cancellation.__exports.CancellationTokenSource = CancellationTokenSource;
	return cancellation.__exports;
}

exports.__require = requireCancellation;
