"use strict";
/**
 * Utilities for bucketing visitors
 * Ported from https://github.com/optimizely/client-js/blob/94b7cd331744d0d6852442cd9fadeb7d4fb212f1/src/core/decision/bucketing.js
 * @module
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.chooseWeightedCandidate = exports.isHoldback = exports.bucketingNumber = exports.TOTAL_POINTS = void 0;
const hashing_1 = __importDefault(require("../lib/hashing"));
exports.TOTAL_POINTS = 10000;
/**
 * Generate a "bucketingNumber" which is a hash based on the ticket, entityId, and seed
 * Designed to be consistent with consistent inputs.
 * @param {string} bucketingId
 * @param {string} entityId
 * @param {hashing.Seed} seed
 * @return {number} between 0 and 9999 representing the bucketing number for the ticket
 * @private
 */
function bucketingNumber(bucketingId, entityId, seed) {
    var result = hashing_1.default.hashToInt(bucketingId + entityId, seed, exports.TOTAL_POINTS);
    return result;
}
exports.bucketingNumber = bucketingNumber;
/**
 * Decide if this ticket should be withheld from a given "entity" (layer, experiment, variation, etc)
 * based on the entity holdback property.
 * @param {string} bucketingId
 * @param {{id: string, holdback: (number|undefined)}} entity
 * @return {boolean} if the ticket should be held back
 */
function isHoldback(bucketingId, entity) {
    return (bucketingNumber(bucketingId, entity.id, hashing_1.default.Seed.IGNORING) <
        (entity.holdback || 0));
}
exports.isHoldback = isHoldback;
/**
 * Choose a weight for a ticket from an array of possible weights based on the entity
 * @param {string} bucketingId
 * @param {string} parentId
 * @param {WeightDistribution[]} candidates
 * @return {string} id of the chosen candidate
 */
function chooseWeightedCandidate(bucketingId, parentId, candidates) {
    var ticketNumber = bucketingNumber(bucketingId, parentId, hashing_1.default.Seed.BUCKETING);
    for (var i = 0; i < candidates.length; i++) {
        if (candidates[i].endOfRange > ticketNumber) {
            return candidates[i].entityId;
        }
    }
    throw new Error('Unable to choose candidate');
}
exports.chooseWeightedCandidate = chooseWeightedCandidate;
