import { __extends, __generator, __read, __spread } from "tslib";
import { stream } from '../../stream/Stream.js';
import { cloneMethod, hasCloneMethod } from '../symbols.js';
import { Arbitrary } from './definition/Arbitrary.js';
import { Shrinkable } from './definition/Shrinkable.js';
import { findOrUndefined } from './helpers/ArrayHelper.js';
var ConstantArbitrary = (function (_super) {
    __extends(ConstantArbitrary, _super);
    function ConstantArbitrary(values) {
        var _this = _super.call(this) || this;
        _this.values = values;
        return _this;
    }
    ConstantArbitrary.prototype.generate = function (mrng) {
        var _this = this;
        if (this.values.length === 1)
            return new Shrinkable(this.values[0]);
        var id = mrng.nextInt(0, this.values.length - 1);
        if (id === 0)
            return new Shrinkable(this.values[0]);
        function g(v) {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4, new Shrinkable(v)];
                    case 1:
                        _a.sent();
                        return [2];
                }
            });
        }
        return new Shrinkable(this.values[id], function () { return stream(g(_this.values[0])); });
    };
    return ConstantArbitrary;
}(Arbitrary));
function constant(value) {
    if (hasCloneMethod(value)) {
        throw new Error('fc.constant does not accept cloneable values, use fc.clonedConstant instead');
    }
    return new ConstantArbitrary([value]);
}
function clonedConstant(value) {
    if (hasCloneMethod(value)) {
        var producer = function () { return value[cloneMethod](); };
        return new ConstantArbitrary([producer]).map(function (c) { return c(); });
    }
    return new ConstantArbitrary([value]);
}
function constantFrom() {
    var values = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        values[_i] = arguments[_i];
    }
    if (values.length === 0) {
        throw new Error('fc.constantFrom expects at least one parameter');
    }
    if (findOrUndefined(values, function (v) { return hasCloneMethod(v); }) != undefined) {
        throw new Error('fc.constantFrom does not accept cloneable values, not supported for the moment');
    }
    return new ConstantArbitrary(__spread(values));
}
export { clonedConstant, constant, constantFrom };
